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 UUID syntax, which is defined in RFC 4530.
051 * Equality and ordering matching will be allowed by default.
052 */
053 public class UUIDSyntax
054 extends AttributeSyntax<AttributeSyntaxCfg>
055 {
056 // The default equality matching rule for this syntax.
057 private EqualityMatchingRule defaultEqualityMatchingRule;
058
059 // The default ordering matching rule for this syntax.
060 private OrderingMatchingRule defaultOrderingMatchingRule;
061
062
063
064 /**
065 * Creates a new instance of this syntax. Note that the only thing that
066 * should be done here is to invoke the default constructor for the
067 * superclass. All initialization should be performed in the
068 * <CODE>initializeSyntax</CODE> method.
069 */
070 public UUIDSyntax()
071 {
072 super();
073 }
074
075
076
077 /**
078 * {@inheritDoc}
079 */
080 public void initializeSyntax(AttributeSyntaxCfg configuration)
081 throws ConfigException
082 {
083 defaultEqualityMatchingRule =
084 DirectoryServer.getEqualityMatchingRule(EMR_UUID_OID);
085 if (defaultEqualityMatchingRule == null)
086 {
087 logError(ERR_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE.get(
088 EMR_UUID_OID, SYNTAX_UUID_NAME));
089 }
090
091 defaultOrderingMatchingRule =
092 DirectoryServer.getOrderingMatchingRule(OMR_UUID_OID);
093 if (defaultOrderingMatchingRule == null)
094 {
095 logError(ERR_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE.get(
096 OMR_UUID_OID, SYNTAX_UUID_NAME));
097 }
098 }
099
100
101
102 /**
103 * Retrieves the common name for this attribute syntax.
104 *
105 * @return The common name for this attribute syntax.
106 */
107 public String getSyntaxName()
108 {
109 return SYNTAX_UUID_NAME;
110 }
111
112
113
114 /**
115 * Retrieves the OID for this attribute syntax.
116 *
117 * @return The OID for this attribute syntax.
118 */
119 public String getOID()
120 {
121 return SYNTAX_UUID_OID;
122 }
123
124
125
126 /**
127 * Retrieves a description for this attribute syntax.
128 *
129 * @return A description for this attribute syntax.
130 */
131 public String getDescription()
132 {
133 return SYNTAX_UUID_DESCRIPTION;
134 }
135
136
137
138 /**
139 * Retrieves the default equality matching rule that will be used for
140 * attributes with this syntax.
141 *
142 * @return The default equality matching rule that will be used for
143 * attributes with this syntax, or <CODE>null</CODE> if equality
144 * matches will not be allowed for this type by default.
145 */
146 public EqualityMatchingRule getEqualityMatchingRule()
147 {
148 return defaultEqualityMatchingRule;
149 }
150
151
152
153 /**
154 * Retrieves the default ordering matching rule that will be used for
155 * attributes with this syntax.
156 *
157 * @return The default ordering matching rule that will be used for
158 * attributes with this syntax, or <CODE>null</CODE> if ordering
159 * matches will not be allowed for this type by default.
160 */
161 public OrderingMatchingRule getOrderingMatchingRule()
162 {
163 return defaultOrderingMatchingRule;
164 }
165
166
167
168 /**
169 * Retrieves the default substring matching rule that will be used for
170 * attributes with this syntax.
171 *
172 * @return The default substring matching rule that will be used for
173 * attributes with this syntax, or <CODE>null</CODE> if substring
174 * matches will not be allowed for this type by default.
175 */
176 public SubstringMatchingRule getSubstringMatchingRule()
177 {
178 // There is no substring matching rule by default.
179 return null;
180 }
181
182
183
184 /**
185 * Retrieves the default approximate matching rule that will be used for
186 * attributes with this syntax.
187 *
188 * @return The default approximate matching rule that will be used for
189 * attributes with this syntax, or <CODE>null</CODE> if approximate
190 * matches will not be allowed for this type by default.
191 */
192 public ApproximateMatchingRule getApproximateMatchingRule()
193 {
194 // There is no approximate matching rule by default.
195 return null;
196 }
197
198
199
200 /**
201 * Indicates whether the provided value is acceptable for use in an attribute
202 * with this syntax. If it is not, then the reason may be appended to the
203 * provided buffer.
204 *
205 * @param value The value for which to make the determination.
206 * @param invalidReason The buffer to which the invalid reason should be
207 * appended.
208 *
209 * @return <CODE>true</CODE> if the provided value is acceptable for use with
210 * this syntax, or <CODE>false</CODE> if not.
211 */
212 public boolean valueIsAcceptable(ByteString value,
213 MessageBuilder invalidReason)
214 {
215 // We will only accept values that look like valid UUIDs. This means that
216 // all values must be in the form HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH,
217 // where "H" represents a hexadecimal digit. First, make sure that the
218 // value is exactly 36 bytes long.
219 String valueString = value.stringValue();
220 if (valueString.length() != 36)
221 {
222
223 invalidReason.append(WARN_ATTR_SYNTAX_UUID_INVALID_LENGTH.get(valueString,
224 valueString.length()));
225 return false;
226 }
227
228 // Next, iterate through each character. Make sure that the 9th, 14th,
229 // 19th, and 24th characters are dashes and the rest are hex digits.
230 for (int i=0; i < 36; i++)
231 {
232 switch (i)
233 {
234 case 8:
235 case 13:
236 case 18:
237 case 23:
238 if (valueString.charAt(i) != '-')
239 {
240
241 invalidReason.append(WARN_ATTR_SYNTAX_UUID_EXPECTED_DASH.get(
242 valueString, i, String.valueOf(valueString.charAt(i))));
243 return false;
244 }
245 break;
246 default:
247 switch (valueString.charAt(i))
248 {
249 case '0':
250 case '1':
251 case '2':
252 case '3':
253 case '4':
254 case '5':
255 case '6':
256 case '7':
257 case '8':
258 case '9':
259 case 'a':
260 case 'b':
261 case 'c':
262 case 'd':
263 case 'e':
264 case 'f':
265 case 'A':
266 case 'B':
267 case 'C':
268 case 'D':
269 case 'E':
270 case 'F':
271 break;
272 default:
273
274 invalidReason.append(WARN_ATTR_SYNTAX_UUID_EXPECTED_HEX.get(
275 valueString, i, String.valueOf(valueString.charAt(i))));
276 return false;
277 }
278 }
279 }
280
281
282 // If we've gotten here, then the value is acceptable.
283 return true;
284 }
285 }
286