001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2006-2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.schema;
028
029
030
031 import org.opends.server.admin.std.server.AttributeSyntaxCfg;
032 import org.opends.server.api.ApproximateMatchingRule;
033 import org.opends.server.api.AttributeSyntax;
034 import org.opends.server.api.EqualityMatchingRule;
035 import org.opends.server.api.OrderingMatchingRule;
036 import org.opends.server.api.SubstringMatchingRule;
037 import org.opends.server.config.ConfigException;
038 import org.opends.server.core.DirectoryServer;
039 import org.opends.server.types.ByteString;
040
041
042
043 import static org.opends.server.loggers.ErrorLogger.*;
044 import static org.opends.messages.SchemaMessages.*;
045 import org.opends.messages.MessageBuilder;
046 import static org.opends.server.schema.SchemaConstants.*;
047
048
049 /**
050 * This class implements the telex number attribute syntax, which contains three
051 * printable strings separated by dollar sign characters. Equality, ordering,
052 * and substring matching will be allowed by default.
053 */
054 public class TelexNumberSyntax
055 extends AttributeSyntax<AttributeSyntaxCfg>
056 {
057 // The default equality matching rule for this syntax.
058 private EqualityMatchingRule defaultEqualityMatchingRule;
059
060 // The default ordering matching rule for this syntax.
061 private OrderingMatchingRule defaultOrderingMatchingRule;
062
063 // The default substring matching rule for this syntax.
064 private SubstringMatchingRule defaultSubstringMatchingRule;
065
066
067
068 /**
069 * Creates a new instance of this syntax. Note that the only thing that
070 * should be done here is to invoke the default constructor for the
071 * superclass. All initialization should be performed in the
072 * <CODE>initializeSyntax</CODE> method.
073 */
074 public TelexNumberSyntax()
075 {
076 super();
077 }
078
079
080
081 /**
082 * {@inheritDoc}
083 */
084 public void initializeSyntax(AttributeSyntaxCfg configuration)
085 throws ConfigException
086 {
087 defaultEqualityMatchingRule =
088 DirectoryServer.getEqualityMatchingRule(EMR_CASE_IGNORE_OID);
089 if (defaultEqualityMatchingRule == null)
090 {
091 logError(ERR_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE.get(
092 EMR_CASE_IGNORE_OID, SYNTAX_TELEX_NAME));
093 }
094
095 defaultOrderingMatchingRule =
096 DirectoryServer.getOrderingMatchingRule(OMR_CASE_IGNORE_OID);
097 if (defaultOrderingMatchingRule == null)
098 {
099 logError(ERR_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE.get(
100 OMR_CASE_IGNORE_OID, SYNTAX_TELEX_NAME));
101 }
102
103 defaultSubstringMatchingRule =
104 DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_OID);
105 if (defaultSubstringMatchingRule == null)
106 {
107 logError(ERR_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE.get(
108 SMR_CASE_IGNORE_OID, SYNTAX_TELEX_NAME));
109 }
110 }
111
112
113
114 /**
115 * Retrieves the common name for this attribute syntax.
116 *
117 * @return The common name for this attribute syntax.
118 */
119 public String getSyntaxName()
120 {
121 return SYNTAX_TELEX_NAME;
122 }
123
124
125
126 /**
127 * Retrieves the OID for this attribute syntax.
128 *
129 * @return The OID for this attribute syntax.
130 */
131 public String getOID()
132 {
133 return SYNTAX_TELEX_OID;
134 }
135
136
137
138 /**
139 * Retrieves a description for this attribute syntax.
140 *
141 * @return A description for this attribute syntax.
142 */
143 public String getDescription()
144 {
145 return SYNTAX_TELEX_DESCRIPTION;
146 }
147
148
149
150 /**
151 * Retrieves the default equality matching rule that will be used for
152 * attributes with this syntax.
153 *
154 * @return The default equality matching rule that will be used for
155 * attributes with this syntax, or <CODE>null</CODE> if equality
156 * matches will not be allowed for this type by default.
157 */
158 public EqualityMatchingRule getEqualityMatchingRule()
159 {
160 return defaultEqualityMatchingRule;
161 }
162
163
164
165 /**
166 * Retrieves the default ordering matching rule that will be used for
167 * attributes with this syntax.
168 *
169 * @return The default ordering matching rule that will be used for
170 * attributes with this syntax, or <CODE>null</CODE> if ordering
171 * matches will not be allowed for this type by default.
172 */
173 public OrderingMatchingRule getOrderingMatchingRule()
174 {
175 return defaultOrderingMatchingRule;
176 }
177
178
179
180 /**
181 * Retrieves the default substring matching rule that will be used for
182 * attributes with this syntax.
183 *
184 * @return The default substring matching rule that will be used for
185 * attributes with this syntax, or <CODE>null</CODE> if substring
186 * matches will not be allowed for this type by default.
187 */
188 public SubstringMatchingRule getSubstringMatchingRule()
189 {
190 return defaultSubstringMatchingRule;
191 }
192
193
194
195 /**
196 * Retrieves the default approximate matching rule that will be used for
197 * attributes with this syntax.
198 *
199 * @return The default approximate matching rule that will be used for
200 * attributes with this syntax, or <CODE>null</CODE> if approximate
201 * matches will not be allowed for this type by default.
202 */
203 public ApproximateMatchingRule getApproximateMatchingRule()
204 {
205 // There is no approximate matching rule by default.
206 return null;
207 }
208
209
210
211 /**
212 * Indicates whether the provided value is acceptable for use in an attribute
213 * with this syntax. If it is not, then the reason may be appended to the
214 * provided buffer.
215 *
216 * @param value The value for which to make the determination.
217 * @param invalidReason The buffer to which the invalid reason should be
218 * appended.
219 *
220 * @return <CODE>true</CODE> if the provided value is acceptable for use with
221 * this syntax, or <CODE>false</CODE> if not.
222 */
223 public boolean valueIsAcceptable(ByteString value,
224 MessageBuilder invalidReason)
225 {
226 // Get a string representation of the value and find its length.
227 String valueString = value.stringValue();
228 int valueLength = valueString.length();
229
230 if (valueLength < 5)
231 {
232
233 invalidReason.append(ERR_ATTR_SYNTAX_TELEX_TOO_SHORT.get(valueString));
234 return false;
235 }
236
237
238 // The first character must be a printable string character.
239 char c = valueString.charAt(0);
240 if (! PrintableString.isPrintableCharacter(c))
241 {
242
243 invalidReason.append(ERR_ATTR_SYNTAX_TELEX_NOT_PRINTABLE.get(
244 valueString, String.valueOf(c), 0));
245 return false;
246 }
247
248
249 // Continue reading until we find a dollar sign. Every intermediate
250 // character must be a printable string character.
251 int pos = 1;
252 for ( ; pos < valueLength; pos++)
253 {
254 c = valueString.charAt(pos);
255 if (c == '$')
256 {
257 pos++;
258 break;
259 }
260 else
261 {
262 if (! PrintableString.isPrintableCharacter(c))
263 {
264
265 invalidReason.append(ERR_ATTR_SYNTAX_TELEX_ILLEGAL_CHAR.get(
266 valueString, String.valueOf(c), pos));
267 }
268 }
269 }
270
271 if (pos >= valueLength)
272 {
273
274 invalidReason.append(ERR_ATTR_SYNTAX_TELEX_TRUNCATED.get(valueString));
275 return false;
276 }
277
278
279 // The next character must be a printable string character.
280 c = valueString.charAt(pos++);
281 if (! PrintableString.isPrintableCharacter(c))
282 {
283
284 invalidReason.append(ERR_ATTR_SYNTAX_TELEX_NOT_PRINTABLE.get(
285 valueString, String.valueOf(c), (pos-1)));
286 return false;
287 }
288
289
290 // Continue reading until we find another dollar sign. Every intermediate
291 // character must be a printable string character.
292 for ( ; pos < valueLength; pos++)
293 {
294 c = valueString.charAt(pos);
295 if (c == '$')
296 {
297 pos++;
298 break;
299 }
300 else
301 {
302 if (! PrintableString.isPrintableCharacter(c))
303 {
304
305 invalidReason.append(ERR_ATTR_SYNTAX_TELEX_ILLEGAL_CHAR.get(
306 valueString, String.valueOf(c), pos));
307 return false;
308 }
309 }
310 }
311
312 if (pos >= valueLength)
313 {
314
315 invalidReason.append(ERR_ATTR_SYNTAX_TELEX_TRUNCATED.get(valueString));
316 return false;
317 }
318
319
320 // The next character must be a printable string character.
321 c = valueString.charAt(pos++);
322 if (! PrintableString.isPrintableCharacter(c))
323 {
324
325 invalidReason.append(ERR_ATTR_SYNTAX_TELEX_NOT_PRINTABLE.get(
326 valueString, String.valueOf(c), (pos-1)));
327 return false;
328 }
329
330
331 // Continue reading until the end of the value. Every intermediate
332 // character must be a printable string character.
333 for ( ; pos < valueLength; pos++)
334 {
335 c = valueString.charAt(pos);
336 if (! PrintableString.isPrintableCharacter(c))
337 {
338
339 invalidReason.append(ERR_ATTR_SYNTAX_TELEX_ILLEGAL_CHAR.get(
340 valueString, String.valueOf(c), pos));
341 return false;
342 }
343 }
344
345
346 // If we've gotten here, then we're at the end of the value and it is
347 // acceptable.
348 return true;
349 }
350 }
351