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 legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008 Sun Microsystems, Inc.
025 */
026package org.forgerock.opendj.server.config.meta;
027
028
029
030import java.util.Collection;
031import java.util.SortedSet;
032import org.forgerock.opendj.config.AdministratorAction;
033import org.forgerock.opendj.config.AliasDefaultBehaviorProvider;
034import org.forgerock.opendj.config.AttributeTypePropertyDefinition;
035import org.forgerock.opendj.config.client.ConcurrentModificationException;
036import org.forgerock.opendj.config.client.ManagedObject;
037import org.forgerock.opendj.config.client.MissingMandatoryPropertiesException;
038import org.forgerock.opendj.config.client.OperationRejectedException;
039import org.forgerock.opendj.config.DefaultBehaviorProvider;
040import org.forgerock.opendj.config.DefinedDefaultBehaviorProvider;
041import org.forgerock.opendj.config.EnumPropertyDefinition;
042import org.forgerock.opendj.config.IntegerPropertyDefinition;
043import org.forgerock.opendj.config.ManagedObjectAlreadyExistsException;
044import org.forgerock.opendj.config.ManagedObjectDefinition;
045import org.forgerock.opendj.config.PropertyException;
046import org.forgerock.opendj.config.PropertyOption;
047import org.forgerock.opendj.config.PropertyProvider;
048import org.forgerock.opendj.config.RelativeInheritedDefaultBehaviorProvider;
049import org.forgerock.opendj.config.server.ConfigurationChangeListener;
050import org.forgerock.opendj.config.server.ServerManagedObject;
051import org.forgerock.opendj.config.StringPropertyDefinition;
052import org.forgerock.opendj.config.Tag;
053import org.forgerock.opendj.config.TopCfgDefn;
054import org.forgerock.opendj.config.UndefinedDefaultBehaviorProvider;
055import org.forgerock.opendj.ldap.DN;
056import org.forgerock.opendj.ldap.LdapException;
057import org.forgerock.opendj.ldap.schema.AttributeType;
058import org.forgerock.opendj.server.config.client.BackendIndexCfgClient;
059import org.forgerock.opendj.server.config.server.BackendIndexCfg;
060
061
062
063/**
064 * An interface for querying the Backend Index managed object
065 * definition meta information.
066 * <p>
067 * Backend Indexes are used to store information that makes it
068 * possible to locate entries very quickly when processing search
069 * operations.
070 */
071public final class BackendIndexCfgDefn extends ManagedObjectDefinition<BackendIndexCfgClient, BackendIndexCfg> {
072
073  /** The singleton configuration definition instance. */
074  private static final BackendIndexCfgDefn INSTANCE = new BackendIndexCfgDefn();
075
076
077
078  /**
079   * Defines the set of permissable values for the "index-type" property.
080   * <p>
081   * Specifies the type(s) of indexing that should be performed for
082   * the associated attribute.
083   * <p>
084   * For equality, presence, and substring index types, the associated
085   * attribute type must have a corresponding matching rule.
086   */
087  public static enum IndexType {
088
089    /**
090     * This index type is used to improve the efficiency of searches
091     * using approximate matching search filters.
092     */
093    APPROXIMATE("approximate"),
094
095
096
097    /**
098     * This index type is used to improve the efficiency of searches
099     * using equality search filters.
100     */
101    EQUALITY("equality"),
102
103
104
105    /**
106     * This index type is used to improve the efficiency of searches
107     * using extensible matching search filters.
108     */
109    EXTENSIBLE("extensible"),
110
111
112
113    /**
114     * This index type is used to improve the efficiency of searches
115     * using "greater than or equal to" or "less then or equal to"
116     * search filters.
117     */
118    ORDERING("ordering"),
119
120
121
122    /**
123     * This index type is used to improve the efficiency of searches
124     * using the presence search filters.
125     */
126    PRESENCE("presence"),
127
128
129
130    /**
131     * This index type is used to improve the efficiency of searches
132     * using substring search filters.
133     */
134    SUBSTRING("substring");
135
136
137
138    /** String representation of the value. */
139    private final String name;
140
141
142
143    /** Private constructor. */
144    private IndexType(String name) { this.name = name; }
145
146
147
148    /** {@inheritDoc} */
149    public String toString() { return name; }
150
151  }
152
153
154
155  /** The "attribute" property definition. */
156  private static final AttributeTypePropertyDefinition PD_ATTRIBUTE;
157
158
159
160  /** The "index-entry-limit" property definition. */
161  private static final IntegerPropertyDefinition PD_INDEX_ENTRY_LIMIT;
162
163
164
165  /** The "index-extensible-matching-rule" property definition. */
166  private static final StringPropertyDefinition PD_INDEX_EXTENSIBLE_MATCHING_RULE;
167
168
169
170  /** The "index-type" property definition. */
171  private static final EnumPropertyDefinition<IndexType> PD_INDEX_TYPE;
172
173
174
175  /** The "substring-length" property definition. */
176  private static final IntegerPropertyDefinition PD_SUBSTRING_LENGTH;
177
178
179
180  /** Build the "attribute" property definition. */
181  static {
182      AttributeTypePropertyDefinition.Builder builder = AttributeTypePropertyDefinition.createBuilder(INSTANCE, "attribute");
183      builder.setOption(PropertyOption.READ_ONLY);
184      builder.setOption(PropertyOption.MANDATORY);
185      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "attribute"));
186      builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<AttributeType>());
187      PD_ATTRIBUTE = builder.getInstance();
188      INSTANCE.registerPropertyDefinition(PD_ATTRIBUTE);
189  }
190
191
192
193  /** Build the "index-entry-limit" property definition. */
194  static {
195      IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition.createBuilder(INSTANCE, "index-entry-limit");
196      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.OTHER, INSTANCE, "index-entry-limit"));
197      DefaultBehaviorProvider<Integer> provider = new RelativeInheritedDefaultBehaviorProvider<Integer>(PluggableBackendCfgDefn.getInstance(), "index-entry-limit", 1);
198      builder.setDefaultBehaviorProvider(provider);
199      builder.setUpperLimit(2147483647);
200      builder.setLowerLimit(0);
201      PD_INDEX_ENTRY_LIMIT = builder.getInstance();
202      INSTANCE.registerPropertyDefinition(PD_INDEX_ENTRY_LIMIT);
203  }
204
205
206
207  /** Build the "index-extensible-matching-rule" property definition. */
208  static {
209      StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "index-extensible-matching-rule");
210      builder.setOption(PropertyOption.MULTI_VALUED);
211      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.OTHER, INSTANCE, "index-extensible-matching-rule"));
212      builder.setDefaultBehaviorProvider(new AliasDefaultBehaviorProvider<String>(INSTANCE, "index-extensible-matching-rule"));
213      builder.setPattern("([a-z][a-z](-[A-Z][A-Z]){0,2}(.(([a-z]{2,3})|\\d))?)|(^\\d.((\\d)+.)+\\d$)", "LOCALE | OID");
214      PD_INDEX_EXTENSIBLE_MATCHING_RULE = builder.getInstance();
215      INSTANCE.registerPropertyDefinition(PD_INDEX_EXTENSIBLE_MATCHING_RULE);
216  }
217
218
219
220  /** Build the "index-type" property definition. */
221  static {
222      EnumPropertyDefinition.Builder<IndexType> builder = EnumPropertyDefinition.createBuilder(INSTANCE, "index-type");
223      builder.setOption(PropertyOption.MULTI_VALUED);
224      builder.setOption(PropertyOption.MANDATORY);
225      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.OTHER, INSTANCE, "index-type"));
226      builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<IndexType>());
227      builder.setEnumClass(IndexType.class);
228      PD_INDEX_TYPE = builder.getInstance();
229      INSTANCE.registerPropertyDefinition(PD_INDEX_TYPE);
230  }
231
232
233
234  /** Build the "substring-length" property definition. */
235  static {
236      IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition.createBuilder(INSTANCE, "substring-length");
237      builder.setOption(PropertyOption.ADVANCED);
238      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.OTHER, INSTANCE, "substring-length"));
239      DefaultBehaviorProvider<Integer> provider = new DefinedDefaultBehaviorProvider<Integer>("6");
240      builder.setDefaultBehaviorProvider(provider);
241      builder.setLowerLimit(3);
242      PD_SUBSTRING_LENGTH = builder.getInstance();
243      INSTANCE.registerPropertyDefinition(PD_SUBSTRING_LENGTH);
244  }
245
246
247
248  // Register the tags associated with this managed object definition.
249  static {
250    INSTANCE.registerTag(Tag.valueOf("database"));
251  }
252
253
254
255  /**
256   * Get the Backend Index configuration definition singleton.
257   *
258   * @return Returns the Backend Index configuration definition
259   *         singleton.
260   */
261  public static BackendIndexCfgDefn getInstance() {
262    return INSTANCE;
263  }
264
265
266
267  /**
268   * Private constructor.
269   */
270  private BackendIndexCfgDefn() {
271    super("backend-index", TopCfgDefn.getInstance());
272  }
273
274
275
276  /** {@inheritDoc} */
277  public BackendIndexCfgClient createClientConfiguration(
278      ManagedObject<? extends BackendIndexCfgClient> impl) {
279    return new BackendIndexCfgClientImpl(impl);
280  }
281
282
283
284  /** {@inheritDoc} */
285  public BackendIndexCfg createServerConfiguration(
286      ServerManagedObject<? extends BackendIndexCfg> impl) {
287    return new BackendIndexCfgServerImpl(impl);
288  }
289
290
291
292  /** {@inheritDoc} */
293  public Class<BackendIndexCfg> getServerConfigurationClass() {
294    return BackendIndexCfg.class;
295  }
296
297
298
299  /**
300   * Get the "attribute" property definition.
301   * <p>
302   * Specifies the name of the attribute for which the index is to be
303   * maintained.
304   *
305   * @return Returns the "attribute" property definition.
306   */
307  public AttributeTypePropertyDefinition getAttributePropertyDefinition() {
308    return PD_ATTRIBUTE;
309  }
310
311
312
313  /**
314   * Get the "index-entry-limit" property definition.
315   * <p>
316   * Specifies the maximum number of entries that are allowed to match
317   * a given index key before that particular index key is no longer
318   * maintained.
319   * <p>
320   * This is analogous to the ALL IDs threshold in the Sun Java System
321   * Directory Server. If this is specified, its value overrides the JE
322   * backend-wide configuration. For no limit, use 0 for the value.
323   *
324   * @return Returns the "index-entry-limit" property definition.
325   */
326  public IntegerPropertyDefinition getIndexEntryLimitPropertyDefinition() {
327    return PD_INDEX_ENTRY_LIMIT;
328  }
329
330
331
332  /**
333   * Get the "index-extensible-matching-rule" property definition.
334   * <p>
335   * The extensible matching rule in an extensible index.
336   * <p>
337   * An extensible matching rule must be specified using either LOCALE
338   * or OID of the matching rule.
339   *
340   * @return Returns the "index-extensible-matching-rule" property definition.
341   */
342  public StringPropertyDefinition getIndexExtensibleMatchingRulePropertyDefinition() {
343    return PD_INDEX_EXTENSIBLE_MATCHING_RULE;
344  }
345
346
347
348  /**
349   * Get the "index-type" property definition.
350   * <p>
351   * Specifies the type(s) of indexing that should be performed for
352   * the associated attribute.
353   * <p>
354   * For equality, presence, and substring index types, the associated
355   * attribute type must have a corresponding matching rule.
356   *
357   * @return Returns the "index-type" property definition.
358   */
359  public EnumPropertyDefinition<IndexType> getIndexTypePropertyDefinition() {
360    return PD_INDEX_TYPE;
361  }
362
363
364
365  /**
366   * Get the "substring-length" property definition.
367   * <p>
368   * The length of substrings in a substring index.
369   *
370   * @return Returns the "substring-length" property definition.
371   */
372  public IntegerPropertyDefinition getSubstringLengthPropertyDefinition() {
373    return PD_SUBSTRING_LENGTH;
374  }
375
376
377
378  /**
379   * Managed object client implementation.
380   */
381  private static class BackendIndexCfgClientImpl implements
382    BackendIndexCfgClient {
383
384    /** Private implementation. */
385    private ManagedObject<? extends BackendIndexCfgClient> impl;
386
387
388
389    /** Private constructor. */
390    private BackendIndexCfgClientImpl(
391        ManagedObject<? extends BackendIndexCfgClient> impl) {
392      this.impl = impl;
393    }
394
395
396
397    /** {@inheritDoc} */
398    public AttributeType getAttribute() {
399      return impl.getPropertyValue(INSTANCE.getAttributePropertyDefinition());
400    }
401
402
403
404    /** {@inheritDoc} */
405    public void setAttribute(AttributeType value) throws PropertyException {
406      impl.setPropertyValue(INSTANCE.getAttributePropertyDefinition(), value);
407    }
408
409
410
411    /** {@inheritDoc} */
412    public Integer getIndexEntryLimit() {
413      return impl.getPropertyValue(INSTANCE.getIndexEntryLimitPropertyDefinition());
414    }
415
416
417
418    /** {@inheritDoc} */
419    public void setIndexEntryLimit(Integer value) {
420      impl.setPropertyValue(INSTANCE.getIndexEntryLimitPropertyDefinition(), value);
421    }
422
423
424
425    /** {@inheritDoc} */
426    public SortedSet<String> getIndexExtensibleMatchingRule() {
427      return impl.getPropertyValues(INSTANCE.getIndexExtensibleMatchingRulePropertyDefinition());
428    }
429
430
431
432    /** {@inheritDoc} */
433    public void setIndexExtensibleMatchingRule(Collection<String> values) {
434      impl.setPropertyValues(INSTANCE.getIndexExtensibleMatchingRulePropertyDefinition(), values);
435    }
436
437
438
439    /** {@inheritDoc} */
440    public SortedSet<IndexType> getIndexType() {
441      return impl.getPropertyValues(INSTANCE.getIndexTypePropertyDefinition());
442    }
443
444
445
446    /** {@inheritDoc} */
447    public void setIndexType(Collection<IndexType> values) {
448      impl.setPropertyValues(INSTANCE.getIndexTypePropertyDefinition(), values);
449    }
450
451
452
453    /** {@inheritDoc} */
454    public int getSubstringLength() {
455      return impl.getPropertyValue(INSTANCE.getSubstringLengthPropertyDefinition());
456    }
457
458
459
460    /** {@inheritDoc} */
461    public void setSubstringLength(Integer value) {
462      impl.setPropertyValue(INSTANCE.getSubstringLengthPropertyDefinition(), value);
463    }
464
465
466
467    /** {@inheritDoc} */
468    public ManagedObjectDefinition<? extends BackendIndexCfgClient, ? extends BackendIndexCfg> definition() {
469      return INSTANCE;
470    }
471
472
473
474    /** {@inheritDoc} */
475    public PropertyProvider properties() {
476      return impl;
477    }
478
479
480
481    /** {@inheritDoc} */
482    public void commit() throws ManagedObjectAlreadyExistsException,
483        MissingMandatoryPropertiesException, ConcurrentModificationException,
484        OperationRejectedException, LdapException {
485      impl.commit();
486    }
487
488
489
490    /** {@inheritDoc} */
491    public String toString() {
492      return impl.toString();
493    }
494  }
495
496
497
498  /**
499   * Managed object server implementation.
500   */
501  private static class BackendIndexCfgServerImpl implements
502    BackendIndexCfg {
503
504    /** Private implementation. */
505    private ServerManagedObject<? extends BackendIndexCfg> impl;
506
507    /** The value of the "attribute" property. */
508    private final AttributeType pAttribute;
509
510    /** The value of the "index-entry-limit" property. */
511    private final Integer pIndexEntryLimit;
512
513    /** The value of the "index-extensible-matching-rule" property. */
514    private final SortedSet<String> pIndexExtensibleMatchingRule;
515
516    /** The value of the "index-type" property. */
517    private final SortedSet<IndexType> pIndexType;
518
519    /** The value of the "substring-length" property. */
520    private final int pSubstringLength;
521
522
523
524    /** Private constructor. */
525    private BackendIndexCfgServerImpl(ServerManagedObject<? extends BackendIndexCfg> impl) {
526      this.impl = impl;
527      this.pAttribute = impl.getPropertyValue(INSTANCE.getAttributePropertyDefinition());
528      this.pIndexEntryLimit = impl.getPropertyValue(INSTANCE.getIndexEntryLimitPropertyDefinition());
529      this.pIndexExtensibleMatchingRule = impl.getPropertyValues(INSTANCE.getIndexExtensibleMatchingRulePropertyDefinition());
530      this.pIndexType = impl.getPropertyValues(INSTANCE.getIndexTypePropertyDefinition());
531      this.pSubstringLength = impl.getPropertyValue(INSTANCE.getSubstringLengthPropertyDefinition());
532    }
533
534
535
536    /** {@inheritDoc} */
537    public void addChangeListener(
538        ConfigurationChangeListener<BackendIndexCfg> listener) {
539      impl.registerChangeListener(listener);
540    }
541
542
543
544    /** {@inheritDoc} */
545    public void removeChangeListener(
546        ConfigurationChangeListener<BackendIndexCfg> listener) {
547      impl.deregisterChangeListener(listener);
548    }
549
550
551
552    /** {@inheritDoc} */
553    public AttributeType getAttribute() {
554      return pAttribute;
555    }
556
557
558
559    /** {@inheritDoc} */
560    public Integer getIndexEntryLimit() {
561      return pIndexEntryLimit;
562    }
563
564
565
566    /** {@inheritDoc} */
567    public SortedSet<String> getIndexExtensibleMatchingRule() {
568      return pIndexExtensibleMatchingRule;
569    }
570
571
572
573    /** {@inheritDoc} */
574    public SortedSet<IndexType> getIndexType() {
575      return pIndexType;
576    }
577
578
579
580    /** {@inheritDoc} */
581    public int getSubstringLength() {
582      return pSubstringLength;
583    }
584
585
586
587    /** {@inheritDoc} */
588    public Class<? extends BackendIndexCfg> configurationClass() {
589      return BackendIndexCfg.class;
590    }
591
592
593
594    /** {@inheritDoc} */
595    public DN dn() {
596      return impl.getDN();
597    }
598
599
600
601    /** {@inheritDoc} */
602    public String toString() {
603      return impl.toString();
604    }
605  }
606}