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