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.PrintableString.*;
047    import static org.opends.server.schema.SchemaConstants.*;
048    import static org.opends.server.util.StaticUtils.*;
049    
050    
051    /**
052     * This class defines the country string attribute syntax, which should be a
053     * two-character ISO 3166 country code.  However, for maintainability, it will
054     * accept any value consisting entirely of two printable characters.  In most
055     * ways, it will behave like the directory string attribute syntax.
056     */
057    public class CountryStringSyntax
058           extends AttributeSyntax<AttributeSyntaxCfg>
059    {
060      // The default approximate matching rule for this syntax.
061      private ApproximateMatchingRule defaultApproximateMatchingRule;
062    
063      // The default equality matching rule for this syntax.
064      private EqualityMatchingRule defaultEqualityMatchingRule;
065    
066      // The default ordering matching rule for this syntax.
067      private OrderingMatchingRule defaultOrderingMatchingRule;
068    
069      // The default substring matching rule for this syntax.
070      private SubstringMatchingRule defaultSubstringMatchingRule;
071    
072    
073    
074      /**
075       * Creates a new instance of this syntax.  Note that the only thing that
076       * should be done here is to invoke the default constructor for the
077       * superclass.  All initialization should be performed in the
078       * <CODE>initializeSyntax</CODE> method.
079       */
080      public CountryStringSyntax()
081      {
082        super();
083      }
084    
085    
086    
087      /**
088       * {@inheritDoc}
089       */
090      public void initializeSyntax(AttributeSyntaxCfg configuration)
091             throws ConfigException
092      {
093        defaultApproximateMatchingRule =
094             DirectoryServer.getApproximateMatchingRule(AMR_DOUBLE_METAPHONE_OID);
095        if (defaultApproximateMatchingRule == null)
096        {
097          logError(ERR_ATTR_SYNTAX_UNKNOWN_APPROXIMATE_MATCHING_RULE.get(
098              AMR_DOUBLE_METAPHONE_OID, SYNTAX_COUNTRY_STRING_NAME));
099        }
100    
101        defaultEqualityMatchingRule =
102             DirectoryServer.getEqualityMatchingRule(EMR_CASE_IGNORE_OID);
103        if (defaultEqualityMatchingRule == null)
104        {
105          logError(ERR_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE.get(
106              EMR_CASE_IGNORE_OID, SYNTAX_COUNTRY_STRING_NAME));
107        }
108    
109        defaultOrderingMatchingRule =
110             DirectoryServer.getOrderingMatchingRule(OMR_CASE_IGNORE_OID);
111        if (defaultOrderingMatchingRule == null)
112        {
113          logError(ERR_ATTR_SYNTAX_UNKNOWN_ORDERING_MATCHING_RULE.get(
114              OMR_CASE_IGNORE_OID, SYNTAX_COUNTRY_STRING_NAME));
115        }
116    
117        defaultSubstringMatchingRule =
118             DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_OID);
119        if (defaultSubstringMatchingRule == null)
120        {
121          logError(ERR_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE.get(
122              SMR_CASE_IGNORE_OID, SYNTAX_COUNTRY_STRING_NAME));
123        }
124      }
125    
126    
127    
128      /**
129       * Retrieves the common name for this attribute syntax.
130       *
131       * @return  The common name for this attribute syntax.
132       */
133      public String getSyntaxName()
134      {
135        return SYNTAX_COUNTRY_STRING_NAME;
136      }
137    
138    
139    
140      /**
141       * Retrieves the OID for this attribute syntax.
142       *
143       * @return  The OID for this attribute syntax.
144       */
145      public String getOID()
146      {
147        return SYNTAX_COUNTRY_STRING_OID;
148      }
149    
150    
151    
152      /**
153       * Retrieves a description for this attribute syntax.
154       *
155       * @return  A description for this attribute syntax.
156       */
157      public String getDescription()
158      {
159        return SYNTAX_COUNTRY_STRING_DESCRIPTION;
160      }
161    
162    
163    
164      /**
165       * Retrieves the default equality matching rule that will be used for
166       * attributes with this syntax.
167       *
168       * @return  The default equality matching rule that will be used for
169       *          attributes with this syntax, or <CODE>null</CODE> if equality
170       *          matches will not be allowed for this type by default.
171       */
172      public EqualityMatchingRule getEqualityMatchingRule()
173      {
174        return defaultEqualityMatchingRule;
175      }
176    
177    
178    
179      /**
180       * Retrieves the default ordering matching rule that will be used for
181       * attributes with this syntax.
182       *
183       * @return  The default ordering matching rule that will be used for
184       *          attributes with this syntax, or <CODE>null</CODE> if ordering
185       *          matches will not be allowed for this type by default.
186       */
187      public OrderingMatchingRule getOrderingMatchingRule()
188      {
189        return defaultOrderingMatchingRule;
190      }
191    
192    
193    
194      /**
195       * Retrieves the default substring matching rule that will be used for
196       * attributes with this syntax.
197       *
198       * @return  The default substring matching rule that will be used for
199       *          attributes with this syntax, or <CODE>null</CODE> if substring
200       *          matches will not be allowed for this type by default.
201       */
202      public SubstringMatchingRule getSubstringMatchingRule()
203      {
204        return defaultSubstringMatchingRule;
205      }
206    
207    
208    
209      /**
210       * Retrieves the default approximate matching rule that will be used for
211       * attributes with this syntax.
212       *
213       * @return  The default approximate matching rule that will be used for
214       *          attributes with this syntax, or <CODE>null</CODE> if approximate
215       *          matches will not be allowed for this type by default.
216       */
217      public ApproximateMatchingRule getApproximateMatchingRule()
218      {
219        return defaultApproximateMatchingRule;
220      }
221    
222    
223    
224      /**
225       * Indicates whether the provided value is acceptable for use in an attribute
226       * with this syntax.  If it is not, then the reason may be appended to the
227       * provided buffer.
228       *
229       * @param  value          The value for which to make the determination.
230       * @param  invalidReason  The buffer to which the invalid reason should be
231       *                        appended.
232       *
233       * @return  <CODE>true</CODE> if the provided value is acceptable for use with
234       *          this syntax, or <CODE>false</CODE> if not.
235       */
236      public boolean valueIsAcceptable(ByteString value,
237                                       MessageBuilder invalidReason)
238      {
239        String stringValue = toLowerCase(value.stringValue());
240        if (stringValue.length() != 2)
241        {
242          invalidReason.append(
243                  ERR_ATTR_SYNTAX_COUNTRY_STRING_INVALID_LENGTH.get(stringValue));
244          return false;
245        }
246    
247    
248        if ((! isPrintableCharacter(stringValue.charAt(0))) ||
249            (! isPrintableCharacter(stringValue.charAt(1))))
250        {
251          invalidReason.append(
252                  ERR_ATTR_SYNTAX_COUNTRY_STRING_NOT_PRINTABLE.get(stringValue));
253          return false;
254        }
255    
256    
257        return true;
258      }
259    }
260