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