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