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}