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