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 printable string attribute syntax, which is simply
051     * a string of characters from a limited ASCII character set (uppercase and
052     * lowercase letters, numeric digits, the space, and a set of various symbols).
053     * By default, they will be treated in a case-insensitive manner, and equality,
054     * ordering, substring, and approximate matching will be allowed.
055     */
056    public class PrintableStringSyntax
057           extends AttributeSyntax<AttributeSyntaxCfg>
058    {
059      // The default approximate matching rule for this syntax.
060      private ApproximateMatchingRule defaultApproximateMatchingRule;
061    
062      // The default equality matching rule for this syntax.
063      private EqualityMatchingRule defaultEqualityMatchingRule;
064    
065      // The default ordering matching rule for this syntax.
066      private OrderingMatchingRule defaultOrderingMatchingRule;
067    
068      // The default substring matching rule for this syntax.
069      private SubstringMatchingRule defaultSubstringMatchingRule;
070    
071    
072    
073      /**
074       * Creates a new instance of this syntax.  Note that the only thing that
075       * should be done here is to invoke the default constructor for the
076       * superclass.  All initialization should be performed in the
077       * <CODE>initializeSyntax</CODE> method.
078       */
079      public PrintableStringSyntax()
080      {
081        super();
082      }
083    
084    
085    
086      /**
087       * {@inheritDoc}
088       */
089      public void initializeSyntax(AttributeSyntaxCfg configuration)
090             throws ConfigException
091      {
092        defaultApproximateMatchingRule =
093             DirectoryServer.getApproximateMatchingRule(AMR_DOUBLE_METAPHONE_OID);
094        if (defaultApproximateMatchingRule == null)
095        {
096          logError(ERR_ATTR_SYNTAX_UNKNOWN_APPROXIMATE_MATCHING_RULE.get(
097              AMR_DOUBLE_METAPHONE_OID, SYNTAX_PRINTABLE_STRING_NAME));
098        }
099    
100        defaultEqualityMatchingRule =
101             DirectoryServer.getEqualityMatchingRule(EMR_CASE_IGNORE_OID);
102        if (defaultEqualityMatchingRule == null)
103        {
104          logError(ERR_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE.get(
105              EMR_CASE_IGNORE_OID, SYNTAX_PRINTABLE_STRING_NAME));
106        }
107    
108        defaultOrderingMatchingRule =
109             DirectoryServer.getOrderingMatchingRule(OMR_CASE_IGNORE_OID);
110        if (defaultOrderingMatchingRule == null)
111        {
112          logError(ERR_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE.get(
113              OMR_CASE_IGNORE_OID, SYNTAX_PRINTABLE_STRING_NAME));
114        }
115    
116        defaultSubstringMatchingRule =
117             DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_OID);
118        if (defaultSubstringMatchingRule == null)
119        {
120          logError(ERR_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE.get(
121              SMR_CASE_IGNORE_OID, SYNTAX_PRINTABLE_STRING_NAME));
122        }
123      }
124    
125    
126    
127      /**
128       * Retrieves the common name for this attribute syntax.
129       *
130       * @return  The common name for this attribute syntax.
131       */
132      public String getSyntaxName()
133      {
134        return SYNTAX_PRINTABLE_STRING_NAME;
135      }
136    
137    
138    
139      /**
140       * Retrieves the OID for this attribute syntax.
141       *
142       * @return  The OID for this attribute syntax.
143       */
144      public String getOID()
145      {
146        return SYNTAX_PRINTABLE_STRING_OID;
147      }
148    
149    
150    
151      /**
152       * Retrieves a description for this attribute syntax.
153       *
154       * @return  A description for this attribute syntax.
155       */
156      public String getDescription()
157      {
158        return SYNTAX_PRINTABLE_STRING_DESCRIPTION;
159      }
160    
161    
162    
163      /**
164       * Retrieves the default equality matching rule that will be used for
165       * attributes with this syntax.
166       *
167       * @return  The default equality matching rule that will be used for
168       *          attributes with this syntax, or <CODE>null</CODE> if equality
169       *          matches will not be allowed for this type by default.
170       */
171      public EqualityMatchingRule getEqualityMatchingRule()
172      {
173        return defaultEqualityMatchingRule;
174      }
175    
176    
177    
178      /**
179       * Retrieves the default ordering matching rule that will be used for
180       * attributes with this syntax.
181       *
182       * @return  The default ordering matching rule that will be used for
183       *          attributes with this syntax, or <CODE>null</CODE> if ordering
184       *          matches will not be allowed for this type by default.
185       */
186      public OrderingMatchingRule getOrderingMatchingRule()
187      {
188        return defaultOrderingMatchingRule;
189      }
190    
191    
192    
193      /**
194       * Retrieves the default substring matching rule that will be used for
195       * attributes with this syntax.
196       *
197       * @return  The default substring matching rule that will be used for
198       *          attributes with this syntax, or <CODE>null</CODE> if substring
199       *          matches will not be allowed for this type by default.
200       */
201      public SubstringMatchingRule getSubstringMatchingRule()
202      {
203        return defaultSubstringMatchingRule;
204      }
205    
206    
207    
208      /**
209       * Retrieves the default approximate matching rule that will be used for
210       * attributes with this syntax.
211       *
212       * @return  The default approximate matching rule that will be used for
213       *          attributes with this syntax, or <CODE>null</CODE> if approximate
214       *          matches will not be allowed for this type by default.
215       */
216      public ApproximateMatchingRule getApproximateMatchingRule()
217      {
218        return defaultApproximateMatchingRule;
219      }
220    
221    
222    
223      /**
224       * Indicates whether the provided value is acceptable for use in an attribute
225       * with this syntax.  If it is not, then the reason may be appended to the
226       * provided buffer.
227       *
228       * @param  value          The value for which to make the determination.
229       * @param  invalidReason  The buffer to which the invalid reason should be
230       *                        appended.
231       *
232       * @return  <CODE>true</CODE> if the provided value is acceptable for use with
233       *          this syntax, or <CODE>false</CODE> if not.
234       */
235      public boolean valueIsAcceptable(ByteString value,
236                                       MessageBuilder invalidReason)
237      {
238        // Check to see if the provided value was null.  If so, then that's not
239        // acceptable.
240        if (value == null)
241        {
242    
243          invalidReason.append(WARN_ATTR_SYNTAX_PRINTABLE_STRING_EMPTY_VALUE.get());
244          return false;
245        }
246    
247    
248        // Get the value as a string and determine its length.  If it is empty, then
249        // that's not acceptable.
250        String valueString = value.stringValue();
251        int    valueLength = valueString.length();
252        if (valueLength == 0)
253        {
254    
255          invalidReason.append(WARN_ATTR_SYNTAX_PRINTABLE_STRING_EMPTY_VALUE.get());
256          return false;
257        }
258    
259    
260        // Iterate through all the characters and see if they are acceptable.
261        for (int i=0; i < valueLength; i++)
262        {
263          char c = valueString.charAt(i);
264          if (! PrintableString.isPrintableCharacter(c))
265          {
266    
267            invalidReason.append(
268                    WARN_ATTR_SYNTAX_PRINTABLE_STRING_ILLEGAL_CHARACTER.get(
269                            valueString, String.valueOf(c), i));
270            return false;
271          }
272        }
273    
274    
275        // If we've gotten here, then the value is OK.
276        return true;
277      }
278    }
279