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 defines the bit string attribute syntax, which is comprised of
051     * a string of binary digits surrounded by single quotes and followed by a
052     * capital letter "B" (e.g., '101001'B).
053     */
054    public class BitStringSyntax
055           extends AttributeSyntax<AttributeSyntaxCfg>
056    {
057      // The default equality matching rule for this syntax.
058      private EqualityMatchingRule defaultEqualityMatchingRule;
059    
060    
061    
062      /**
063       * Creates a new instance of this syntax.  Note that the only thing that
064       * should be done here is to invoke the default constructor for the
065       * superclass.  All initialization should be performed in the
066       * <CODE>initializeSyntax</CODE> method.
067       */
068      public BitStringSyntax()
069      {
070        super();
071      }
072    
073    
074    
075      /**
076       * {@inheritDoc}
077       */
078      public void initializeSyntax(AttributeSyntaxCfg configuration)
079             throws ConfigException
080      {
081        defaultEqualityMatchingRule =
082             DirectoryServer.getEqualityMatchingRule(EMR_BIT_STRING_OID);
083        if (defaultEqualityMatchingRule == null)
084        {
085          logError(ERR_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE.get(
086              EMR_BIT_STRING_OID, SYNTAX_BIT_STRING_NAME));
087        }
088      }
089    
090    
091    
092      /**
093       * Retrieves the common name for this attribute syntax.
094       *
095       * @return  The common name for this attribute syntax.
096       */
097      public String getSyntaxName()
098      {
099        return SYNTAX_BIT_STRING_NAME;
100      }
101    
102    
103    
104      /**
105       * Retrieves the OID for this attribute syntax.
106       *
107       * @return  The OID for this attribute syntax.
108       */
109      public String getOID()
110      {
111        return SYNTAX_BIT_STRING_OID;
112      }
113    
114    
115    
116      /**
117       * Retrieves a description for this attribute syntax.
118       *
119       * @return  A description for this attribute syntax.
120       */
121      public String getDescription()
122      {
123        return SYNTAX_BIT_STRING_DESCRIPTION;
124      }
125    
126    
127    
128      /**
129       * Retrieves the default equality matching rule that will be used for
130       * attributes with this syntax.
131       *
132       * @return  The default equality matching rule that will be used for
133       *          attributes with this syntax, or <CODE>null</CODE> if equality
134       *          matches will not be allowed for this type by default.
135       */
136      public EqualityMatchingRule getEqualityMatchingRule()
137      {
138        return defaultEqualityMatchingRule;
139      }
140    
141    
142    
143      /**
144       * Retrieves the default ordering matching rule that will be used for
145       * attributes with this syntax.
146       *
147       * @return  The default ordering matching rule that will be used for
148       *          attributes with this syntax, or <CODE>null</CODE> if ordering
149       *          matches will not be allowed for this type by default.
150       */
151      public OrderingMatchingRule getOrderingMatchingRule()
152      {
153        // Ordering matches are not allowed by default.
154        return null;
155      }
156    
157    
158    
159      /**
160       * Retrieves the default substring matching rule that will be used for
161       * attributes with this syntax.
162       *
163       * @return  The default substring matching rule that will be used for
164       *          attributes with this syntax, or <CODE>null</CODE> if substring
165       *          matches will not be allowed for this type by default.
166       */
167      public SubstringMatchingRule getSubstringMatchingRule()
168      {
169        // Substring matches are not allowed by default.
170        return null;
171      }
172    
173    
174    
175      /**
176       * Retrieves the default approximate matching rule that will be used for
177       * attributes with this syntax.
178       *
179       * @return  The default approximate matching rule that will be used for
180       *          attributes with this syntax, or <CODE>null</CODE> if approximate
181       *          matches will not be allowed for this type by default.
182       */
183      public ApproximateMatchingRule getApproximateMatchingRule()
184      {
185        // Approximate matches are not allowed by default.
186        return null;
187      }
188    
189    
190    
191      /**
192       * Indicates whether the provided value is acceptable for use in an attribute
193       * with this syntax.  If it is not, then the reason may be appended to the
194       * provided buffer.
195       *
196       * @param  value          The value for which to make the determination.
197       * @param  invalidReason  The buffer to which the invalid reason should be
198       *                        appended.
199       *
200       * @return  <CODE>true</CODE> if the provided value is acceptable for use with
201       *          this syntax, or <CODE>false</CODE> if not.
202       */
203      public boolean valueIsAcceptable(ByteString value,
204                                       MessageBuilder invalidReason)
205      {
206        String valueString = value.stringValue().toUpperCase();
207    
208        int length = valueString.length();
209        if (length < 3)
210        {
211          invalidReason.append(
212                  WARN_ATTR_SYNTAX_BIT_STRING_TOO_SHORT.get(value.stringValue()));
213          return false;
214        }
215    
216    
217        if ((valueString.charAt(0) != '\'') ||
218            (valueString.charAt(length-2) != '\'') ||
219            (valueString.charAt(length-1) != 'B'))
220        {
221          invalidReason.append(
222                  WARN_ATTR_SYNTAX_BIT_STRING_NOT_QUOTED.get(value.stringValue()));
223          return false;
224        }
225    
226    
227        for (int i=1; i < (length-2); i++)
228        {
229          switch (valueString.charAt(i))
230          {
231            case '0':
232            case '1':
233              // These characters are fine.
234              break;
235            default:
236              invalidReason.append(WARN_ATTR_SYNTAX_BIT_STRING_INVALID_BIT.get(
237                      value.stringValue(), String.valueOf(valueString.charAt(i))));
238              return false;
239          }
240        }
241    
242    
243        // If we've gotten here, then everything is fine.
244        return true;
245      }
246    }
247