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    import org.opends.messages.Message;
029    
030    
031    
032    import org.opends.server.admin.std.server.AttributeSyntaxCfg;
033    import org.opends.server.api.ApproximateMatchingRule;
034    import org.opends.server.api.AttributeSyntax;
035    import org.opends.server.api.AttributeValueDecoder;
036    import org.opends.server.api.EqualityMatchingRule;
037    import org.opends.server.api.OrderingMatchingRule;
038    import org.opends.server.api.SubstringMatchingRule;
039    import org.opends.server.config.ConfigException;
040    import org.opends.server.core.DirectoryServer;
041    import org.opends.server.protocols.asn1.ASN1OctetString;
042    import org.opends.server.types.AttributeValue;
043    import org.opends.server.types.ByteString;
044    import org.opends.server.types.DirectoryException;
045    
046    
047    import org.opends.server.types.ResultCode;
048    
049    import static org.opends.server.loggers.ErrorLogger.*;
050    import static org.opends.messages.SchemaMessages.*;
051    import org.opends.messages.MessageBuilder;
052    import static org.opends.server.schema.SchemaConstants.*;
053    
054    
055    /**
056     * This class defines the Boolean attribute syntax, which only allows values of
057     * "TRUE" or "FALSE" (although this implementation is more flexible and will
058     * also allow "YES", "ON", or "1" instead of "TRUE", or "NO", "OFF", or "0"
059     * instead of "FALSE").  Only equality matching is allowed by default for this
060     * syntax.
061     */
062    public class BooleanSyntax
063           extends AttributeSyntax<AttributeSyntaxCfg>
064    {
065      // The default equality matching rule for this syntax.
066      private EqualityMatchingRule defaultEqualityMatchingRule;
067    
068    
069    
070      /**
071       * A {@link Boolean} attribute value decoder for this syntax.
072       */
073      public static final AttributeValueDecoder<Boolean> DECODER =
074        new AttributeValueDecoder<Boolean>()
075      {
076        /**
077         * {@inheritDoc}
078         */
079        public Boolean decode(AttributeValue value) throws DirectoryException
080        {
081          ByteString octetString = value.getNormalizedValue();
082          return decodeBooleanValue(octetString);
083        }
084      };
085    
086    
087    
088      /**
089       * Creates a new instance of this syntax.  Note that the only thing that
090       * should be done here is to invoke the default constructor for the
091       * superclass.  All initialization should be performed in the
092       * <CODE>initializeSyntax</CODE> method.
093       */
094      public BooleanSyntax()
095      {
096        super();
097      }
098    
099    
100    
101      /**
102       * {@inheritDoc}
103       */
104      public void initializeSyntax(AttributeSyntaxCfg configuration)
105             throws ConfigException
106      {
107        defaultEqualityMatchingRule =
108             DirectoryServer.getEqualityMatchingRule(EMR_BOOLEAN_OID);
109        if (defaultEqualityMatchingRule == null)
110        {
111          logError(ERR_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE.get(
112              EMR_BOOLEAN_OID, SYNTAX_BOOLEAN_NAME));
113        }
114      }
115    
116    
117    
118      /**
119       * Retrieves the common name for this attribute syntax.
120       *
121       * @return  The common name for this attribute syntax.
122       */
123      public String getSyntaxName()
124      {
125        return SYNTAX_BOOLEAN_NAME;
126      }
127    
128    
129    
130      /**
131       * Retrieves the OID for this attribute syntax.
132       *
133       * @return  The OID for this attribute syntax.
134       */
135      public String getOID()
136      {
137        return SYNTAX_BOOLEAN_OID;
138      }
139    
140    
141    
142      /**
143       * Retrieves a description for this attribute syntax.
144       *
145       * @return  A description for this attribute syntax.
146       */
147      public String getDescription()
148      {
149        return SYNTAX_BOOLEAN_DESCRIPTION;
150      }
151    
152    
153    
154      /**
155       * Retrieves the default equality matching rule that will be used for
156       * attributes with this syntax.
157       *
158       * @return  The default equality matching rule that will be used for
159       *          attributes with this syntax, or <CODE>null</CODE> if equality
160       *          matches will not be allowed for this type by default.
161       */
162      public EqualityMatchingRule getEqualityMatchingRule()
163      {
164        return defaultEqualityMatchingRule;
165      }
166    
167    
168    
169      /**
170       * Retrieves the default ordering matching rule that will be used for
171       * attributes with this syntax.
172       *
173       * @return  The default ordering matching rule that will be used for
174       *          attributes with this syntax, or <CODE>null</CODE> if ordering
175       *          matches will not be allowed for this type by default.
176       */
177      public OrderingMatchingRule getOrderingMatchingRule()
178      {
179        // Ordering matches are not allowed by default.
180        return null;
181      }
182    
183    
184    
185      /**
186       * Retrieves the default substring matching rule that will be used for
187       * attributes with this syntax.
188       *
189       * @return  The default substring matching rule that will be used for
190       *          attributes with this syntax, or <CODE>null</CODE> if substring
191       *          matches will not be allowed for this type by default.
192       */
193      public SubstringMatchingRule getSubstringMatchingRule()
194      {
195        // Substring matches are not allowed by default.
196        return null;
197      }
198    
199    
200    
201      /**
202       * Retrieves the default approximate matching rule that will be used for
203       * attributes with this syntax.
204       *
205       * @return  The default approximate matching rule that will be used for
206       *          attributes with this syntax, or <CODE>null</CODE> if approximate
207       *          matches will not be allowed for this type by default.
208       */
209      public ApproximateMatchingRule getApproximateMatchingRule()
210      {
211        // Approximate matches are not allowed by default.
212        return null;
213      }
214    
215    
216    
217      /**
218       * Indicates whether the provided value is acceptable for use in an attribute
219       * with this syntax.  If it is not, then the reason may be appended to the
220       * provided buffer.
221       *
222       * @param  value          The value for which to make the determination.
223       * @param  invalidReason  The buffer to which the invalid reason should be
224       *                        appended.
225       *
226       * @return  <CODE>true</CODE> if the provided value is acceptable for use with
227       *          this syntax, or <CODE>false</CODE> if not.
228       */
229      public boolean valueIsAcceptable(ByteString value,
230                                       MessageBuilder invalidReason)
231      {
232        String valueString = value.stringValue().toUpperCase();
233    
234        boolean returnValue = (valueString.equals("TRUE") ||
235                               valueString.equals("YES") ||
236                               valueString.equals("ON") ||
237                               valueString.equals("1") ||
238                               valueString.equals("FALSE") ||
239                               valueString.equals("NO") ||
240                               valueString.equals("OFF") ||
241                               valueString.equals("0"));
242    
243        if (! returnValue)
244        {
245          invalidReason.append(WARN_ATTR_SYNTAX_ILLEGAL_BOOLEAN.get(
246                  value.stringValue()));
247        }
248    
249        return returnValue;
250      }
251    
252    
253    
254      /**
255       * Retrieves an attribute value containing a representation of the provided
256       * boolean value.
257       *
258       * @param  b  The boolean value for which to retrieve the attribute value.
259       *
260       * @return  The attribute value created from the provided boolean value.
261       */
262      public static AttributeValue createBooleanValue(boolean b)
263      {
264        if (b)
265        {
266          return new AttributeValue(new ASN1OctetString("TRUE"),
267                                    new ASN1OctetString("TRUE"));
268        }
269        else
270        {
271          return new AttributeValue(new ASN1OctetString("FALSE"),
272                                    new ASN1OctetString("FALSE"));
273        }
274      }
275    
276    
277    
278      /**
279       * Decodes the provided normalized value as a boolean.
280       *
281       * @param  normalizedValue  The normalized value to decode as a boolean.
282       *
283       * @return  The decoded boolean value.
284       *
285       * @throws  DirectoryException  If the provided value cannot be decoded as a
286       *                              boolean.
287       */
288      public static boolean decodeBooleanValue(ByteString normalizedValue)
289             throws DirectoryException
290      {
291        String valueString = normalizedValue.stringValue();
292        if (valueString.equals("TRUE"))
293        {
294          return true;
295        }
296        else if (valueString.equals("FALSE"))
297        {
298          return false;
299        }
300        else
301        {
302          Message message = WARN_ATTR_SYNTAX_ILLEGAL_BOOLEAN.get(valueString);
303          throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
304                                       message);
305        }
306      }
307    }
308