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