opendj-sdk/opendj-core/clirr-ignored-api-changes.xml
@@ -178,4 +178,24 @@ <method>org.forgerock.opendj.ldap.LDAPOptions setDecodeOptions(org.forgerock.opendj.ldap.DecodeOptions)</method> <justification>OPENDJ-1197: Method return type has changed due to reification</justification> </difference> <difference> <className>org/forgerock/opendj/ldap/Assertion</className> <differenceType>7012</differenceType> <method>java.lang.Object createIndexQuery(org.forgerock.opendj.ldap.spi.IndexQueryFactory)</method> <justification>OPENDJ-1308 Migrate schema support: allows decoupling indexing from a specific backend</justification> </difference> <difference> <className>org/forgerock/opendj/ldap/schema/MatchingRuleImpl</className> <differenceType>7012</differenceType> <method>org.forgerock.opendj.ldap.spi.Indexer getIndexer()</method> <justification>OPENDJ-1308 Migrate schema support: allows decoupling indexing from a specific backend</justification> </difference> <difference> <className>org/forgerock/opendj/ldap/schema/MatchingRuleImpl</className> <differenceType>7012</differenceType> <method>boolean isIndexingSupported()</method> <justification>OPENDJ-1308 Migrate schema support: allows decoupling indexing from a specific backend</justification> </difference> </differences> opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Assertion.java
@@ -26,10 +26,13 @@ */ package org.forgerock.opendj.ldap; import org.forgerock.opendj.ldap.spi.IndexQueryFactory; /** * A compiled attribute value assertion. */ public interface Assertion { /** * Indicates whether the provided attribute value should be considered a * match for this assertion value according to the matching rule. @@ -41,4 +44,20 @@ * match, or {@code UNDEFINED} if the result is undefined. */ ConditionResult matches(ByteSequence normalizedAttributeValue); /** * Returns an index query appropriate for the provided attribute * value assertion. * * @param <T> * The type of index query created by the {@code factory}. * @param factory * The index query factory which should be used to * construct the index query. * @return The index query appropriate for the provided attribute * value assertion. * @throws DecodeException * If an error occurs while generating the index query. */ <T> T createIndexQuery(IndexQueryFactory<T> factory) throws DecodeException; } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractApproximateMatchingRuleImpl.java
@@ -28,6 +28,7 @@ import org.forgerock.opendj.ldap.Assertion; import org.forgerock.opendj.ldap.ByteSequence; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.spi.Indexer; /** * This class implements an approximate matching rule that matches normalized @@ -35,6 +36,8 @@ */ abstract class AbstractApproximateMatchingRuleImpl extends AbstractMatchingRuleImpl { private final Indexer indexer = new DefaultIndexer("approximate"); AbstractApproximateMatchingRuleImpl() { // Nothing to do. } @@ -45,4 +48,9 @@ return DefaultAssertion.approximate(normalizeAttributeValue(schema, assertionValue)); } /** {@inheritDoc} */ @Override public Indexer getIndexer() { return indexer; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractEqualityMatchingRuleImpl.java
@@ -28,6 +28,7 @@ import org.forgerock.opendj.ldap.Assertion; import org.forgerock.opendj.ldap.ByteSequence; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.spi.Indexer; /** * This class implements an equality matching rule that matches normalized @@ -35,6 +36,8 @@ */ abstract class AbstractEqualityMatchingRuleImpl extends AbstractMatchingRuleImpl { private final Indexer indexer = new DefaultIndexer("equality"); AbstractEqualityMatchingRuleImpl() { // Nothing to do. } @@ -45,4 +48,9 @@ return DefaultAssertion.equality(normalizeAttributeValue(schema, assertionValue)); } /** {@inheritDoc} */ @Override public Indexer getIndexer() { return indexer; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractMatchingRuleImpl.java
@@ -26,13 +26,18 @@ */ package org.forgerock.opendj.ldap.schema; import java.util.Collection; import java.util.Comparator; import java.util.List; import org.forgerock.opendj.ldap.Assertion; import org.forgerock.opendj.ldap.ByteSequence; import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.ConditionResult; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.spi.IndexQueryFactory; import org.forgerock.opendj.ldap.spi.Indexer; import org.forgerock.opendj.ldap.spi.IndexingOptions; /** * This class implements a default equality or approximate matching rule that @@ -41,7 +46,7 @@ abstract class AbstractMatchingRuleImpl implements MatchingRuleImpl { static final class DefaultAssertion implements Assertion { /** The ID of the DB index that to use with this assertion.*/ /** The ID of the DB index to use with this assertion.*/ private final String indexID; private final ByteSequence normalizedAssertionValue; @@ -61,12 +66,42 @@ public ConditionResult matches(final ByteSequence attributeValue) { return ConditionResult.valueOf(normalizedAssertionValue.equals(attributeValue)); } public <T> T createIndexQuery(IndexQueryFactory<T> factory) throws DecodeException { return factory.createExactMatchQuery(indexID, normalizedAssertionValue); } } final class DefaultIndexer implements Indexer { /** The ID of the DB index to use with this indexer.*/ private final String indexID; DefaultIndexer(String indexID) { this.indexID = indexID; } @Override public void createKeys(Schema schema, ByteSequence value, IndexingOptions options, Collection<ByteString> keys) throws DecodeException { keys.add(normalizeAttributeValue(schema, value)); } @Override public String getIndexID() { return indexID; } }; private static final Assertion UNDEFINED_ASSERTION = new Assertion() { public ConditionResult matches(final ByteSequence attributeValue) { return ConditionResult.UNDEFINED; } public <T> T createIndexQuery(IndexQueryFactory<T> factory) throws DecodeException { // Subclassing this class will always work, albeit inefficiently. // This is better than throwing an exception for no good reason. return factory.createMatchAllQuery(); } }; private static final Comparator<ByteSequence> DEFAULT_COMPARATOR = @@ -104,4 +139,11 @@ throws DecodeException { return UNDEFINED_ASSERTION; } /** {@inheritDoc} */ @Override public boolean isIndexingSupported() { return getIndexer() != null; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractOrderingMatchingRuleImpl.java
@@ -31,12 +31,17 @@ import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.ConditionResult; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.spi.IndexQueryFactory; import org.forgerock.opendj.ldap.spi.Indexer; /** * This class implements a default ordering matching rule that matches * normalized values in byte order. */ abstract class AbstractOrderingMatchingRuleImpl extends AbstractMatchingRuleImpl { private final Indexer indexer = new DefaultIndexer("ordering"); AbstractOrderingMatchingRuleImpl() { // Nothing to do. } @@ -48,6 +53,11 @@ public ConditionResult matches(final ByteSequence attributeValue) { return ConditionResult.valueOf(attributeValue.compareTo(normAssertion) < 0); } @Override public <T> T createIndexQuery(IndexQueryFactory<T> factory) throws DecodeException { return factory.createRangeMatchQuery("ordering", ByteString.empty(), normAssertion, false, false); } }; } @@ -59,6 +69,11 @@ public ConditionResult matches(final ByteSequence attributeValue) { return ConditionResult.valueOf(attributeValue.compareTo(normAssertion) >= 0); } @Override public <T> T createIndexQuery(IndexQueryFactory<T> factory) throws DecodeException { return factory.createRangeMatchQuery("ordering", normAssertion, ByteString.empty(), true, false); } }; } @@ -70,6 +85,17 @@ public ConditionResult matches(final ByteSequence attributeValue) { return ConditionResult.valueOf(attributeValue.compareTo(normAssertion) <= 0); } @Override public <T> T createIndexQuery(IndexQueryFactory<T> factory) throws DecodeException { return factory.createRangeMatchQuery("ordering", ByteString.empty(), normAssertion, false, true); } }; } /** {@inheritDoc} */ @Override public Indexer getIndexer() { return indexer; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/AbstractSubstringMatchingRuleImpl.java
@@ -28,8 +28,10 @@ import static com.forgerock.opendj.ldap.CoreMessages.*; import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.TreeSet; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.opendj.ldap.Assertion; @@ -38,6 +40,9 @@ import org.forgerock.opendj.ldap.ByteStringBuilder; import org.forgerock.opendj.ldap.ConditionResult; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.spi.IndexQueryFactory; import org.forgerock.opendj.ldap.spi.Indexer; import org.forgerock.opendj.ldap.spi.IndexingOptions; import com.forgerock.opendj.util.SubstringReader; @@ -46,18 +51,34 @@ * normalized substring assertion values in byte order. */ abstract class AbstractSubstringMatchingRuleImpl extends AbstractMatchingRuleImpl { static class DefaultSubstringAssertion implements Assertion { /** * Default assertion implementation for substring matching rules. * For example, with the assertion value "initial*any1*any2*any3*final", * the assertion will be decomposed like this: * <ul> * <li>normInitial will contain "initial"</li> * <li>normAnys will contain [ "any1", "any2", "any3" ]</li> * <li>normFinal will contain "final"</li> * </ul> */ static final class DefaultSubstringAssertion implements Assertion { /** Normalized substring for the text before the first '*' character. */ private final ByteString normInitial; /** Normalized substrings for all text chunks in between '*' characters. */ private final ByteString[] normAnys; /** Normalized substring for the text after the last '*' character. */ private final ByteString normFinal; protected DefaultSubstringAssertion(final ByteString normInitial, private DefaultSubstringAssertion(final ByteString normInitial, final ByteString[] normAnys, final ByteString normFinal) { this.normInitial = normInitial; this.normAnys = normAnys; this.normFinal = normFinal; } /** {@inheritDoc} */ @Override public ConditionResult matches(final ByteSequence attributeValue) { final int valueLength = attributeValue.length(); @@ -125,12 +146,118 @@ return ConditionResult.TRUE; } /** {@inheritDoc} */ @Override public <T> T createIndexQuery(IndexQueryFactory<T> factory) throws DecodeException { final Collection<T> subqueries = new LinkedList<T>(); if (normInitial != null) { // relies on the fact that equality indexes are also ordered subqueries.add(rangeMatch(factory, "equality", normInitial)); } if (normAnys != null) { for (ByteString normAny : normAnys) { substringMatch(factory, normAny, subqueries); } } if (normFinal != null) { substringMatch(factory, normFinal, subqueries); } if (normInitial != null) { // Add this one last to minimize the risk to run the same search twice // (possible overlapping with the use of equality index at the start of this method) substringMatch(factory, normInitial, subqueries); } return factory.createIntersectionQuery(subqueries); } private <T> T rangeMatch(IndexQueryFactory<T> factory, String indexID, ByteSequence lower) { // Iterate through all the keys that have this value as the prefix. // Set the upper bound for a range search. // We need a key for the upper bound that is of equal length // but slightly greater than the lower bound. final ByteStringBuilder upper = new ByteStringBuilder(lower); for (int i = upper.length() - 1; i >= 0; i--) { if (upper.byteAt(i) == 0xFF) { // We have to carry the overflow to the more significant byte. upper.setByte(i, (byte) 0); } else { // No overflow, we can stop. upper.setByte(i, (byte) (upper.byteAt(i) + 1)); break; } } // Read the range: lower <= keys < upper. return factory.createRangeMatchQuery(indexID, lower, upper, true, false); } private <T> void substringMatch(final IndexQueryFactory<T> factory, final ByteString normSubstring, final Collection<T> subqueries) { int substrLength = factory.getIndexingOptions().substringKeySize(); // There are two cases, depending on whether the user-provided // substring is smaller than the configured index substring length or not. if (normSubstring.length() < substrLength) { subqueries.add(rangeMatch(factory, "substring", normSubstring)); } else { // Break the value up into fragments of length equal to the // index substring length, and read those keys. // Eliminate duplicates by putting the keys into a set. final TreeSet<ByteSequence> substringKeys = new TreeSet<ByteSequence>(); // Example: The value is ABCDE and the substring length is 3. // We produce the keys ABC BCD CDE. for (int first = 0, last = substrLength; last <= normSubstring.length(); first++, last++) { substringKeys.add(normSubstring.subSequence(first, first + substrLength)); } for (ByteSequence key : substringKeys) { subqueries.add(factory.createExactMatchQuery("substring", key)); } } } } final class SubstringIndexer implements Indexer { /** {@inheritDoc} */ @Override public void createKeys(Schema schema, ByteSequence value, IndexingOptions options, Collection<ByteString> keys) throws DecodeException { final ByteString normValue = normalizeAttributeValue(schema, value); final int substringKeySize = options.substringKeySize(); // Example: The value is ABCDE and the substring length is 3. // We produce the keys ABC BCD CDE DE E // To find values containing a short substring such as DE, // iterate through keys with prefix DE. To find values // containing a longer substring such as BCDE, read keys BCD and CDE. for (int i = 0, remain = normValue.length(); remain > 0; i++, remain--) { int len = Math.min(substringKeySize, remain); keys.add(normValue.subSequence(i, i + len)); } } /** {@inheritDoc} */ @Override public String getIndexID() { return "substring"; } } private SubstringIndexer substringIndexer = new SubstringIndexer(); AbstractSubstringMatchingRuleImpl() { // Nothing to do. } /** {@inheritDoc} */ @Override public Assertion getAssertion(final Schema schema, final ByteSequence assertionValue) throws DecodeException { @@ -143,7 +270,6 @@ List<ByteSequence> anyStrings = null; final String valueString = assertionValue.toString(); if (valueString.length() == 1 && valueString.charAt(0) == '*') { return getSubstringAssertion(schema, initialString, anyStrings, finalString); } @@ -156,8 +282,7 @@ initialString = normalizeSubString(schema, bytes); } if (reader.remaining() == 0) { throw DecodeException.error(WARN_ATTR_SYNTAX_SUBSTRING_NO_WILDCARDS.get(assertionValue .toString())); throw DecodeException.error(WARN_ATTR_SYNTAX_SUBSTRING_NO_WILDCARDS.get(assertionValue)); } while (true) { reader.read(); @@ -165,7 +290,7 @@ if (reader.remaining() > 0) { if (bytes.length() == 0) { throw DecodeException.error(WARN_ATTR_SYNTAX_SUBSTRING_CONSECUTIVE_WILDCARDS .get(assertionValue.toString(), reader.pos())); .get(assertionValue, reader.pos())); } if (anyStrings == null) { anyStrings = new LinkedList<ByteSequence>(); @@ -182,6 +307,7 @@ return getSubstringAssertion(schema, initialString, anyStrings, finalString); } /** {@inheritDoc} */ @Override public Assertion getSubstringAssertion(final Schema schema, final ByteSequence subInitial, final List<? extends ByteSequence> subAnyElements, final ByteSequence subFinal) @@ -436,4 +562,11 @@ return ByteString.empty(); } } /** {@inheritDoc} */ @Override public Indexer getIndexer() { return substringIndexer; } } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/CertificateExactMatchingRuleImpl.java
@@ -23,7 +23,6 @@ * * Copyright 2006-2009 Sun Microsystems, Inc. * Portions Copyright 2013-2014 Manuel Gaupp * Copyright 2014 ForgeRock AS */ package org.forgerock.opendj.ldap.schema; @@ -43,8 +42,8 @@ import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.ByteStringBuilder; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.GSERParser; import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.ldap.GSERParser; import com.forgerock.opendj.util.StaticUtils; @@ -55,7 +54,7 @@ * X.509 and referenced in RFC 4523. */ final class CertificateExactMatchingRuleImpl extends AbstractMatchingRuleImpl { extends AbstractEqualityMatchingRuleImpl { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/EqualLengthApproximateMatchingRuleImpl.java
@@ -31,6 +31,7 @@ import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.ConditionResult; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.spi.IndexQueryFactory; /** * This class implements an extremely simple approximate matching rule that will @@ -46,6 +47,11 @@ public ConditionResult matches(final ByteSequence attributeValue) { return ConditionResult.valueOf(attributeValue.length() == assertionValue.length()); } @Override public <T> T createIndexQuery(IndexQueryFactory<T> factory) throws DecodeException { return factory.createExactMatchQuery("approximate", ByteString.valueOf(assertionValue.length())); } }; } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/KeywordEqualityMatchingRuleImpl.java
@@ -34,6 +34,8 @@ import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.ConditionResult; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.spi.IndexQueryFactory; import org.forgerock.opendj.ldap.spi.Indexer; /** * This class implements the keywordMatch matching rule defined in X.520. That @@ -107,9 +109,20 @@ return false; } } @Override public <T> T createIndexQuery(IndexQueryFactory<T> factory) throws DecodeException { return factory.createMatchAllQuery(); } }; } /** {@inheritDoc} */ @Override public Indexer getIndexer() { return null; } public ByteString normalizeAttributeValue(final Schema schema, final ByteSequence value) { return ByteString.valueOf(normalize(value)); } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRule.java
@@ -43,6 +43,7 @@ import org.forgerock.opendj.ldap.ByteSequence; import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.spi.Indexer; /** @@ -361,6 +362,15 @@ } /** * Returns the indexer for this matching rule. * * @return the indexer for this matching rule. */ public Indexer getIndexer() { return impl.getIndexer(); } /** * Returns the name or OID for this schema definition. If it has one or more * names, then the primary name will be returned. If it does not have any * names, then the OID will be returned. opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/MatchingRuleImpl.java
@@ -33,6 +33,7 @@ import org.forgerock.opendj.ldap.ByteSequence; import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.spi.Indexer; /** * This interface defines the set of methods that must be implemented to define @@ -139,4 +140,18 @@ ByteString normalizeAttributeValue(Schema schema, ByteSequence value) throws DecodeException; /** * Returns the indexer for this matching rule. * * @return the indexer for this matching rule. */ Indexer getIndexer(); /** * Returns whether a backend can build an index for this matching rule. * * @return true a backend can build an index for this matching rule, * false otherwise. */ boolean isIndexingSupported(); } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/IndexQueryFactory.java
New file @@ -0,0 +1,117 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. * Portions Copyright 2014 ForgeRock AS */ package org.forgerock.opendj.ldap.spi; import java.util.Collection; import org.forgerock.opendj.ldap.ByteSequence; /** * A factory for creating arbitrarily complex index queries. This * interface is implemented by the underlying backend implementation * and passed to extensible matching rules so that they can construct * arbitrarily complex index queries. * * @param <T> * The type of query created by this factory. */ public interface IndexQueryFactory<T> { /** * Returns a query requesting an index record matching the provided key. * * @param indexID * An identifier of the index type. * @param key * A byte sequence containing the key. * @return A query requesting the index record matching the key. */ T createExactMatchQuery(String indexID, ByteSequence key); /** * Returns a query requesting all index records. A backend implementation * may choose to return all or no records as part of the optimization. * * @return A query requesting all index records. */ T createMatchAllQuery(); /** * Returns a query requesting all index records in the specified range. * * @param indexID * An identifier of the index type. * @param lower * The lower bound of the range. A 0 length byte array indicates no * lower bound and the range will start from the smallest key. * @param upper * The upper bound of the range. A 0 length byte array indicates no * upper bound and the range will end at the largest key. * @param lowerIncluded * true if a key exactly matching the lower bound is included in * the range, false if only keys strictly greater than the lower * bound are included. This value is ignored if the lower bound is * not specified. * @param upperIncluded * true if a key exactly matching the upper bound is included in * the range, false if only keys strictly less than the upper bound * are included. This value is ignored if the upper bound is not * specified. * @return A query requesting all index records in the specified range. */ T createRangeMatchQuery(String indexID, ByteSequence lower, ByteSequence upper, boolean lowerIncluded, boolean upperIncluded); /** * Returns a query which returns the intersection of a collection of * sub-queries. * * @param subqueries * A collection of sub-queries. * @return A query which returns the intersection of a collection of * sub-queries. */ T createIntersectionQuery(Collection<T> subqueries); /** * Returns a query which combines the results of a collection of * sub-queries. * * @param subqueries * A collection of sub-queries. * @return A query which combines the results of a collection of * sub-queries. */ T createUnionQuery(Collection<T> subqueries); /** * Returns the indexing options for this factory. * * @return the indexing options for this factory. */ IndexingOptions getIndexingOptions(); } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/Indexer.java
New file @@ -0,0 +1,69 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. */ package org.forgerock.opendj.ldap.spi; import java.util.Collection; import org.forgerock.opendj.ldap.ByteSequence; import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.schema.Schema; /** * This class is registered with a Backend and it provides call- backs * for indexing attribute values. An index implementation will use * this interface to create the keys for an attribute value. */ public interface Indexer { /** * Returns an index identifier associated with this indexer. An identifier * should be selected based on the matching rule type. A unique identifier * will map to a unique index database in the backend implementation. If * multiple matching rules need to share the index database, the * corresponding indexers should always use the same identifier. * * @return index ID A String containing the ID associated with this indexer. */ String getIndexID(); /** * Generates the set of index keys for an attribute. * * @param schema * The schema in which the associated matching rule is defined. * @param value * The attribute value for which keys are required. * @param options * The indexing options * @param keys * A collection where to add the created keys. * @throws DecodeException if an error occurs while normalizing the value */ void createKeys(Schema schema, ByteSequence value, IndexingOptions options, Collection<ByteString> keys) throws DecodeException; } opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/spi/IndexingOptions.java
New file @@ -0,0 +1,41 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * Copyright 2014 ForgeRock AS */ package org.forgerock.opendj.ldap.spi; /** * Contains options indicating how indexing must be performed. */ public interface IndexingOptions { /** * Returns the maximum size to use when building the keys for the * "substring" index. * * @return the maximum size to use when building the keys for the * "substring" index. */ int substringKeySize(); }