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.AttributeValueDecoder;
035    import org.opends.server.api.EqualityMatchingRule;
036    import org.opends.server.api.OrderingMatchingRule;
037    import org.opends.server.api.SubstringMatchingRule;
038    import org.opends.server.config.ConfigException;
039    import org.opends.server.core.DirectoryServer;
040    import org.opends.server.types.AttributeValue;
041    import org.opends.server.types.ByteString;
042    import org.opends.server.types.DirectoryException;
043    import org.opends.server.types.DN;
044    
045    import static org.opends.server.loggers.ErrorLogger.*;
046    import static org.opends.server.loggers.debug.DebugLogger.*;
047    import org.opends.server.loggers.debug.DebugTracer;
048    import org.opends.server.types.DebugLogLevel;
049    import static org.opends.messages.SchemaMessages.*;
050    import org.opends.messages.MessageBuilder;
051    import static org.opends.server.schema.SchemaConstants.*;
052    
053    
054    /**
055     * This class defines the distinguished name attribute syntax, which is used for
056     * attributes that hold distinguished names (DNs).  Equality and substring
057     * matching will be allowed by default.
058     */
059    public class DistinguishedNameSyntax
060           extends AttributeSyntax<AttributeSyntaxCfg>
061    {
062      /**
063       * The tracer object for the debug logger.
064       */
065      private static final DebugTracer TRACER = getTracer();
066    
067    
068    
069      // The default equality matching rule for this syntax.
070      private EqualityMatchingRule defaultEqualityMatchingRule;
071    
072      // The default substring matching rule for this syntax.
073      private SubstringMatchingRule defaultSubstringMatchingRule;
074    
075    
076    
077      /**
078       * A {@link DN} attribute value decoder for this syntax.
079       */
080      public static final AttributeValueDecoder<DN> DECODER =
081        new AttributeValueDecoder<DN>()
082      {
083        /**
084         * {@inheritDoc}
085         */
086        public DN decode(AttributeValue value) throws DirectoryException
087        {
088          return DN.decode(value.getStringValue());
089        }
090      };
091    
092    
093    
094      /**
095       * Creates a new instance of this syntax.  Note that the only thing that
096       * should be done here is to invoke the default constructor for the
097       * superclass.  All initialization should be performed in the
098       * <CODE>initializeSyntax</CODE> method.
099       */
100      public DistinguishedNameSyntax()
101      {
102        super();
103      }
104    
105    
106    
107      /**
108       * {@inheritDoc}
109       */
110      public void initializeSyntax(AttributeSyntaxCfg configuration)
111             throws ConfigException
112      {
113        defaultEqualityMatchingRule =
114             DirectoryServer.getEqualityMatchingRule(EMR_DN_OID);
115        if (defaultEqualityMatchingRule == null)
116        {
117          logError(ERR_ATTR_SYNTAX_UNKNOWN_EQUALITY_MATCHING_RULE.get(
118              EMR_DN_OID, SYNTAX_DN_NAME));
119        }
120    
121        defaultSubstringMatchingRule =
122             DirectoryServer.getSubstringMatchingRule(SMR_CASE_IGNORE_OID);
123        if (defaultSubstringMatchingRule == null)
124        {
125          logError(ERR_ATTR_SYNTAX_UNKNOWN_SUBSTRING_MATCHING_RULE.get(
126              SMR_CASE_IGNORE_OID, SYNTAX_DN_NAME));
127        }
128      }
129    
130    
131    
132      /**
133       * Retrieves the common name for this attribute syntax.
134       *
135       * @return  The common name for this attribute syntax.
136       */
137      public String getSyntaxName()
138      {
139        return SYNTAX_DN_NAME;
140      }
141    
142    
143    
144      /**
145       * Retrieves the OID for this attribute syntax.
146       *
147       * @return  The OID for this attribute syntax.
148       */
149      public String getOID()
150      {
151        return SYNTAX_DN_OID;
152      }
153    
154    
155    
156      /**
157       * Retrieves a description for this attribute syntax.
158       *
159       * @return  A description for this attribute syntax.
160       */
161      public String getDescription()
162      {
163        return SYNTAX_DN_DESCRIPTION;
164      }
165    
166    
167    
168      /**
169       * Retrieves the default equality matching rule that will be used for
170       * attributes with this syntax.
171       *
172       * @return  The default equality matching rule that will be used for
173       *          attributes with this syntax, or <CODE>null</CODE> if equality
174       *          matches will not be allowed for this type by default.
175       */
176      public EqualityMatchingRule getEqualityMatchingRule()
177      {
178        return defaultEqualityMatchingRule;
179      }
180    
181    
182    
183      /**
184       * Retrieves the default ordering matching rule that will be used for
185       * attributes with this syntax.
186       *
187       * @return  The default ordering matching rule that will be used for
188       *          attributes with this syntax, or <CODE>null</CODE> if ordering
189       *          matches will not be allowed for this type by default.
190       */
191      public OrderingMatchingRule getOrderingMatchingRule()
192      {
193        // There is no ordering matching rule by default.
194        return null;
195      }
196    
197    
198    
199      /**
200       * Retrieves the default substring matching rule that will be used for
201       * attributes with this syntax.
202       *
203       * @return  The default substring matching rule that will be used for
204       *          attributes with this syntax, or <CODE>null</CODE> if substring
205       *          matches will not be allowed for this type by default.
206       */
207      public SubstringMatchingRule getSubstringMatchingRule()
208      {
209        return defaultSubstringMatchingRule;
210      }
211    
212    
213    
214      /**
215       * Retrieves the default approximate matching rule that will be used for
216       * attributes with this syntax.
217       *
218       * @return  The default approximate matching rule that will be used for
219       *          attributes with this syntax, or <CODE>null</CODE> if approximate
220       *          matches will not be allowed for this type by default.
221       */
222      public ApproximateMatchingRule getApproximateMatchingRule()
223      {
224        // There is no approximate matching rule by default.
225        return null;
226      }
227    
228    
229    
230      /**
231       * Indicates whether the provided value is acceptable for use in an attribute
232       * with this syntax.  If it is not, then the reason may be appended to the
233       * provided buffer.
234       *
235       * @param  value          The value for which to make the determination.
236       * @param  invalidReason  The buffer to which the invalid reason should be
237       *                        appended.
238       *
239       * @return  <CODE>true</CODE> if the provided value is acceptable for use with
240       *          this syntax, or <CODE>false</CODE> if not.
241       */
242      public boolean valueIsAcceptable(ByteString value,
243                                       MessageBuilder invalidReason)
244      {
245        // Use the DN code to make this determination.
246        try
247        {
248          DN.decode(value.stringValue());
249    
250          return true;
251        }
252        catch (DirectoryException de)
253        {
254          if (debugEnabled())
255          {
256            TRACER.debugCaught(DebugLogLevel.ERROR, de);
257          }
258    
259          invalidReason.append(de.getMessageObject());
260          return false;
261        }
262        catch (Exception e)
263        {
264          if (debugEnabled())
265          {
266            TRACER.debugCaught(DebugLogLevel.ERROR, e);
267          }
268    
269    
270          invalidReason.append(ERR_ATTR_SYNTAX_DN_INVALID.get(value.stringValue(),
271                                          String.valueOf(e)));
272    
273          return false;
274        }
275      }
276    }
277