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