From 7ddf5a923866031a7034f457715d6a5e4ecbca67 Mon Sep 17 00:00:00 2001
From: sin <sin@localhost>
Date: Sat, 31 Jan 2009 07:06:11 +0000
Subject: [PATCH] Integrating the changes related to Collation indexing support
---
opends/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java | 1802 +++++++++++++++++++++++++++++++--------------------------
1 files changed, 990 insertions(+), 812 deletions(-)
diff --git a/opends/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java b/opends/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java
index 8868702..0237d4a 100644
--- a/opends/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java
+++ b/opends/src/server/org/opends/server/schema/CollationMatchingRuleFactory.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2009 Sun Microsystems, Inc.
*/
@@ -44,21 +44,27 @@
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
+import java.util.TreeSet;
import org.opends.messages.Message;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.meta.CollationMatchingRuleCfgDefn.
MatchingRuleType;
+import org.opends.server.api.ExtensibleIndexer;
+import org.opends.server.api.IndexQueryFactory;
import org.opends.server.api.MatchingRuleFactory;
import org.opends.server.admin.std.server.CollationMatchingRuleCfg;
import org.opends.server.api.ExtensibleMatchingRule;
import org.opends.server.api.MatchingRule;
+import org.opends.server.backends.jeb.AttributeIndex;
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
+import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConditionResult;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DirectoryException;
+import org.opends.server.types.IndexConfig;
import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
@@ -68,6 +74,8 @@
import static org.opends.messages.CoreMessages.*;
import static org.opends.messages.ConfigMessages.*;
import static org.opends.server.util.StaticUtils.*;
+import static org.opends.server.api.ExtensibleIndexer.*;
+import static org.opends.server.util.ServerConstants.*;
@@ -118,9 +126,9 @@
}
-/**
- * Creates a new instance of CollationMatchingRuleFactory.
- */
+ /**
+ * Creates a new instance of CollationMatchingRuleFactory.
+ */
public CollationMatchingRuleFactory()
{
//Initialize the matchingRules.
@@ -130,8 +138,8 @@
/**
- * {@inheritDoc}
- */
+ * {@inheritDoc}
+ */
@Override
public final Collection<MatchingRule> getMatchingRules()
{
@@ -140,16 +148,16 @@
- /**
- * Adds a new mapping of OID and MatchingRule.
- *
- * @param oid OID of the matching rule
- * @param matchingRule instance of a MatchingRule.
- */
+ /**
+ * Adds a new mapping of OID and MatchingRule.
+ *
+ * @param oid OID of the matching rule
+ * @param matchingRule instance of a MatchingRule.
+ */
private final void addMatchingRule(String oid,
MatchingRule matchingRule)
{
- matchingRules.put(oid, matchingRule);
+ matchingRules.put(oid, matchingRule);
}
@@ -179,10 +187,10 @@
/**
- * Reads the configuration and initializes matching rule types.
- *
- * @param ruleTypes The Set containing allowed matching rule types.
- */
+ * Reads the configuration and initializes matching rule types.
+ *
+ * @param ruleTypes The Set containing allowed matching rule types.
+ */
private void initializeMatchingRuleTypes(SortedSet<MatchingRuleType>
ruleTypes)
{
@@ -209,19 +217,19 @@
substringMatchingRuleType = true;
break;
default:
- //No default values allowed.
+ //No default values allowed.
}
}
}
- /**
- * Creates a new Collator instance.
- *
- * @param locale Locale for the collator
- * @return Returns a new Collator instance
- */
+ /**
+ * Creates a new Collator instance.
+ *
+ * @param locale Locale for the collator
+ * @return Returns a new Collator instance
+ */
private Collator createCollator(Locale locale)
{
Collator collator = Collator.getInstance(locale);
@@ -232,9 +240,9 @@
- /**
- * {@inheritDoc}
- */
+ /**
+ * {@inheritDoc}
+ */
@Override
public void initializeMatchingRule(CollationMatchingRuleCfg configuration)
throws ConfigException, InitializationException
@@ -271,7 +279,7 @@
Message msg =
WARN_ATTR_INVALID_COLLATION_MATCHING_RULE_LOCALE.
get(collation,configuration.dn().toNormalizedString(),
- languageTag);
+ languageTag);
logError(msg);
}
@@ -332,7 +340,6 @@
for(String collation:configuration.getCollation())
{
CollationMapper mapper = new CollationMapper(collation);
- String nOID = mapper.getNumericOID();
String languageTag = mapper.getLanguageTag();
Locale locale = getLocale(languageTag);
createLessThanMatchingRule(mapper,locale);
@@ -352,10 +359,10 @@
}
catch (DirectoryException de)
{
- Message message = WARN_CONFIG_SCHEMA_MR_CONFLICTING_MR.get(
- String.valueOf(configuration.dn()), de.getMessageObject());
- adminActionRequired = true;
- messages.add(message);
+ Message message = WARN_CONFIG_SCHEMA_MR_CONFLICTING_MR.get(
+ String.valueOf(configuration.dn()), de.getMessageObject());
+ adminActionRequired = true;
+ messages.add(message);
}
currentConfig = configuration;
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
@@ -405,7 +412,7 @@
Message msg =
WARN_ATTR_INVALID_COLLATION_MATCHING_RULE_LOCALE.
get(collation,configuration.dn().toNormalizedString(),
- languageTag);
+ languageTag);
unacceptableReasons.add(msg);
configAcceptable = false;
continue;
@@ -417,11 +424,11 @@
/**
- * Creates Less-than Matching Rule.
- *
- * @param mapper CollationMapper containing OID and the language Tag.
- * @param locale Locale value
- */
+ * Creates Less-than Matching Rule.
+ *
+ * @param mapper CollationMapper containing OID and the language Tag.
+ * @param locale Locale value
+ */
private void createLessThanMatchingRule(CollationMapper mapper,Locale locale)
{
if(!lessThanMatchingRuleType)
@@ -449,12 +456,12 @@
- /**
- * Creates Less-Than-Equal-To Matching Rule.
- *
- * @param mapper CollationMapper containing OID and the language Tag.
- * @param locale Locale value
- */
+ /**
+ * Creates Less-Than-Equal-To Matching Rule.
+ *
+ * @param mapper CollationMapper containing OID and the language Tag.
+ * @param locale Locale value
+ */
private void createLessThanOrEqualToMatchingRule(CollationMapper mapper,
Locale locale)
{
@@ -484,12 +491,12 @@
- /**
- * Creates Equality Matching Rule.
- *
- * @param mapper CollationMapper containing OID and the language Tag.
- * @param locale Locale value
- */
+ /**
+ * Creates Equality Matching Rule.
+ *
+ * @param mapper CollationMapper containing OID and the language Tag.
+ * @param locale Locale value
+ */
private void createEqualityMatchingRule(CollationMapper mapper,Locale locale)
{
if(!equalityMatchingRuleType)
@@ -510,37 +517,37 @@
names.add(lTag);
matchingRule =
- new CollationEqualityMatchingRule(nOID,names,locale);
+ new CollationEqualityMatchingRule(nOID,
+ Collections.<String>emptySet(),locale);
addMatchingRule(nOID, matchingRule);
// Register OID.3 as the equality matching rule.
String OID = mapper.getNumericOID() + ".3";
MatchingRule equalityMatchingRule = getMatchingRule(OID);
- Collection<String> equalityNames = new HashSet<String>();
if(equalityMatchingRule!=null)
{
for(String name: equalityMatchingRule.getAllNames())
{
- equalityNames.add(name);
+ names.add(name);
}
}
- equalityNames.add(lTag+".eq");
- equalityNames.add(lTag+".3");
+ names.add(lTag+".eq");
+ names.add(lTag+".3");
equalityMatchingRule =
- new CollationEqualityMatchingRule(OID,equalityNames,locale);
+ new CollationEqualityMatchingRule(OID,names,locale);
addMatchingRule(OID, equalityMatchingRule);
}
/**
- * Creates Greater-than-equal-to Matching Rule.
- *
- * @param mapper CollationMapper containing OID and the language Tag.
- * @param locale Locale value
- */
+ * Creates Greater-than-equal-to Matching Rule.
+ *
+ * @param mapper CollationMapper containing OID and the language Tag.
+ * @param locale Locale value
+ */
private void createGreaterThanOrEqualToMatchingRule(CollationMapper mapper,
Locale locale)
{
@@ -569,12 +576,12 @@
- /**
- * Creates Greater-than Matching Rule.
- *
- * @param mapper CollationMapper containing OID and the language Tag.
- * @param locale Locale value
- */
+ /**
+ * Creates Greater-than Matching Rule.
+ *
+ * @param mapper CollationMapper containing OID and the language Tag.
+ * @param locale Locale value
+ */
private void createGreaterThanMatchingRule(CollationMapper mapper,
Locale locale)
{
@@ -603,12 +610,12 @@
- /**
- * Creates substring Matching Rule.
- *
- * @param mapper CollationMapper containing OID and the language Tag.
- * @param locale Locale value
- */
+ /**
+ * Creates substring Matching Rule.
+ *
+ * @param mapper CollationMapper containing OID and the language Tag.
+ * @param locale Locale value
+ */
private void createSubstringMatchingRule(CollationMapper mapper,Locale locale)
{
if(!substringMatchingRuleType)
@@ -636,12 +643,12 @@
- /**
- * Verifies if the locale is supported by the JVM.
- *
- * @param lTag The language tag specified in the configuration.
- * @return Locale The locale correspoding to the languageTag.
- */
+ /**
+ * Verifies if the locale is supported by the JVM.
+ *
+ * @param lTag The language tag specified in the configuration.
+ * @return Locale The locale correspoding to the languageTag.
+ */
private Locale getLocale(String lTag)
{
//Separates the language and the country from the locale.
@@ -685,35 +692,51 @@
- /**
- *Collation rule for Equality matching rule.
- */
- private final class CollationEqualityMatchingRule
- extends ExtensibleMatchingRule
+ /**
+ * Collation Extensible matching rule.
+ */
+ private abstract class CollationMatchingRule
+ extends ExtensibleMatchingRule
{
//Names for this class.
private final Collection<String> names;
+
+
//Collator for performing equality match.
- private final Collator collator;
+ protected final Collator collator;
+
+
//Numeric OID of the rule.
private final String nOID;
+
+ //Locale associated with this rule.
+ private final Locale locale;
+
+
+
+ //Indexer of this rule.
+ protected ExtensibleIndexer indexer;
+
+
+
/**
- * Constructs a new CollationEqualityMatchingRule.
+ * Constructs a new CollationMatchingRule.
*
* @param nOID OID of the collation matching rule
* @param names names of this matching rule
* @param locale Locale of the collation matching rule
*/
- private CollationEqualityMatchingRule(String nOID,Collection<String> names,
+ private CollationMatchingRule(String nOID,Collection<String> names,
Locale locale)
{
super();
this.names = names;
- this.collator =createCollator(locale);
+ this.collator = createCollator(locale);
+ this.locale = locale;
this.nOID = nOID;
}
@@ -747,6 +770,7 @@
}
+
/**
* {@inheritDoc}
*/
@@ -782,6 +806,74 @@
/**
+ * Returns the name of the index database for this matching rule.
+ * An index name for this rule will be based upon the Locale. This will
+ * ensure that multiple collation matching rules corresponding to the same
+ * Locale can share the same index database.
+ * @return The name of the index for this matching rule.
+ */
+ public String getIndexName()
+ {
+ String language = locale.getLanguage();
+ String country = locale.getCountry();
+ String variant = locale.getVariant();
+ StringBuilder builder = new StringBuilder(language);
+ if (country != null && country.length() > 0)
+ {
+ builder.append("_");
+ builder.append(locale.getCountry());
+ }
+ if (variant != null && variant.length() > 0)
+ {
+ builder.append("_");
+ builder.append(locale.getVariant());
+ }
+ return builder.toString();
+ }
+
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<ExtensibleIndexer> getIndexers(IndexConfig config)
+ {
+ if(indexer == null)
+ {
+ //The default implementation contains shared indexer and doesn't use the
+ //config.
+ indexer = new CollationSharedExtensibleIndexer(this);
+ }
+ return Collections.singletonList(indexer);
+ }
+ }
+
+
+
+ /**
+ *Collation rule for Equality matching rule.
+ */
+ private final class CollationEqualityMatchingRule
+ extends CollationMatchingRule
+ {
+ /**
+ * Constructs a new CollationEqualityMatchingRule.
+ *
+ * @param nOID OID of the collation matching rule
+ * @param names names of this matching rule
+ * @param locale Locale of the collation matching rule
+ */
+ private CollationEqualityMatchingRule(String nOID,Collection<String> names,
+ Locale locale)
+ {
+ super(nOID,names,locale);
+ }
+
+
+
+ /**
* {@inheritDoc}
*/
@Override
@@ -794,18 +886,18 @@
- /**
- * Indicates whether the two provided normalized values are equal to
- * each other.
- *
- * @param value1 The normalized form of the first value to
- * compare.
- * @param value2 The normalized form of the second value to
- * compare.
- *
- * @return {@code true} if the provided values are equal, or
- * {@code false} if not.
- */
+ /**
+ * Indicates whether the two provided normalized values are equal to
+ * each other.
+ *
+ * @param value1 The normalized form of the first value to
+ * compare.
+ * @param value2 The normalized form of the second value to
+ * compare.
+ *
+ * @return {@code true} if the provided values are equal, or
+ * {@code false} if not.
+ */
private boolean areEqual(ByteString value1, ByteString value2)
{
return Arrays.equals(value1.value(), value2.value());
@@ -829,23 +921,35 @@
return ConditionResult.FALSE;
}
}
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> T createIndexQuery(ByteString assertionValue,
+ IndexQueryFactory<T> factory) throws DirectoryException
+ {
+ //Normalize the assertion value.
+ ByteString normalValue = normalizeValue(assertionValue);
+ return factory.createExactMatchQuery(
+ indexer.getExtensibleIndexID(),
+ normalValue.value());
+ }
}
- /**
- * Collation rule for Substring matching rule.
- */
+
+ /**
+ * Collation rule for Substring matching rule.
+ */
private final class CollationSubstringMatchingRule
- extends ExtensibleMatchingRule
+ extends CollationMatchingRule
{
- //Names for this class.
- private final Collection<String> names;
+ //Substring Indexer associated with this instance.
+ private CollationSubstringExtensibleIndexer subIndexer;
- //Collator for performing equality match.
- private final Collator collator;
-
- //Numeric OID of the rule.
- private final String nOID;
/**
@@ -858,10 +962,7 @@
private CollationSubstringMatchingRule(String nOID,
Collection<String> names,Locale locale)
{
- super();
- this.names = names;
- this.collator =createCollator(locale);
- this.nOID = nOID;
+ super(nOID,names,locale);
}
@@ -870,67 +971,6 @@
* {@inheritDoc}
*/
@Override
- public String getName()
- {
- //Concatenate all the names and return.
- StringBuilder builder = new StringBuilder();
- for(String name: getAllNames())
- {
- builder.append(name);
- builder.append("\b");
- }
- return builder.toString();
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Collection<String> getAllNames()
- {
- return Collections.unmodifiableCollection(names);
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getOID()
- {
- return nOID;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getDescription()
- {
- return null;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getSyntaxOID()
- {
- return SYNTAX_DIRECTORY_STRING_OID;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
public ByteString normalizeValue(ByteString value)
throws DirectoryException
{
@@ -940,12 +980,81 @@
- /**
- * {@inheritDoc}
- */
- @Override
- public ByteString normalizeAssertionValue(ByteString value)
- throws DirectoryException
+ /**
+ * Utility class which abstracts a substring assertion value.
+ */
+ private final class Assertion
+ {
+ //Initial part of the substring filter.
+ private String subInitial;
+
+
+ //any parts of the substring filter.
+ private List<String> subAny;
+
+
+ //Final part of the substring filter.
+ private String subFinal;
+
+
+
+ /**
+ * Creates a new instance of Assertion.
+ * @param subInitial Initial part of the filter.
+ * @param subAny Any part of the filter.
+ * @param subFinal Final part of the filter.
+ */
+ Assertion(String subInitial, List<String> subAny, String subFinal)
+ {
+ this.subInitial = subInitial;
+ this.subAny = subAny;
+ this.subFinal = subFinal;
+ }
+
+
+
+ /**
+ * Returns the Initial part of the assertion.
+ * @return Initial part of assertion.
+ */
+ private String getInitial()
+ {
+ return subInitial;
+ }
+
+
+
+ /**
+ * Returns the any part of the assertion.
+ * @return Any part of the assertion.
+ */
+ private List<String> getAny()
+ {
+ return subAny;
+ }
+
+
+
+ /**
+ * Returns the final part of the assertion.
+ * @return Final part of the assertion.
+ */
+ private String getFinal()
+ {
+ return subFinal;
+ }
+ }
+
+
+
+ /**
+ * Parses the assertion from a given value.
+ * @param value The value that needs to be parsed.
+ * @return The parsed Assertion object containing the
+ * @throws org.opends.server.types.DirectoryException
+ */
+ private Assertion parseAssertion(ByteString value)
+ throws DirectoryException
{
// Get a string representation of the value.
String filterString = value.stringValue();
@@ -973,7 +1082,7 @@
if (asteriskPositions.isEmpty())
{
Message message = ERR_SEARCH_FILTER_SUBSTRING_NO_ASTERISKS.get(
- filterString, 0, endPos);
+ filterString, 0, endPos);
throw new DirectoryException(
ResultCode.PROTOCOL_ERROR, message);
}
@@ -1094,7 +1203,19 @@
subFinal = filterString.substring(firstPos+1, length + firstPos + 1);
}
}
+ return new Assertion(subInitial, subAny, subFinal);
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ByteString normalizeAssertionValue(ByteString value)
+ throws DirectoryException {
+ Assertion assertion = parseAssertion(value);
+ String subInitial = assertion.getInitial();
// Normalize the Values in the following format:
// initialLength, initial, numberofany, anyLength1, any1, anyLength2,
// any2, ..., anyLengthn, anyn, finalLength, final
@@ -1117,8 +1238,8 @@
normalizedList.add((int)initialBytes[i]);
}
}
- if(subAny.size()==0)
- {
+ List<String> subAny = assertion.getAny();
+ if (subAny.size() == 0) {
normalizedList.add(0);
}
else
@@ -1136,7 +1257,8 @@
}
}
}
- if(subFinal ==null)
+ String subFinal = assertion.getFinal();
+ if (subFinal == null)
{
normalizedList.add(0);
}
@@ -1238,7 +1360,7 @@
}
assertPos = assertPos + anyLength;
}
- }
+ }
int finalLength = 0xFF & assertionBytes[assertPos++];
if(finalLength!=0)
@@ -1267,23 +1389,371 @@
}
return ConditionResult.TRUE;
- }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final Collection<ExtensibleIndexer> getIndexers(IndexConfig config)
+ {
+ Collection<ExtensibleIndexer> indexers =
+ new ArrayList<ExtensibleIndexer>();
+ int substrLength = 6; //Default substring length;
+ if(subIndexer == null)
+ {
+ if(config != null)
+ {
+ substrLength = config.getSubstringLength();
+ }
+ subIndexer = new CollationSubstringExtensibleIndexer(this,
+ substrLength);
+ }
+ else
+ {
+ if(config !=null)
+ {
+ if(config.getSubstringLength() !=subIndexer.gerSubstringLength())
+ {
+ subIndexer.setSubstringLength(substrLength);
+ }
+ }
+ }
+
+ if(indexer == null)
+ {
+ indexer = new CollationSharedExtensibleIndexer(this);
+ }
+ indexers.add(subIndexer);
+ indexers.add(indexer);
+ return indexers;
+ }
+
+
+
+ /**
+ * Decomposes an attribute value into a set of substring index keys.
+ *
+ * @param attValue Tthe normalized attribute value
+ * @param set A set into which the keys will be inserted.
+ */
+ private void subtringKeys(ByteString attValue,
+ Set<byte[]> keys)
+ {
+ String value = attValue.stringValue();
+ int keyLength = subIndexer.gerSubstringLength();
+ for (int i = 0, remain = value.length(); remain > 0; i++, remain--)
+ {
+ int len = Math.min(keyLength, remain);
+ byte[] keyBytes = makeSubstringKey(value, i, len);
+ keys.add(keyBytes);
+ }
+ }
+
+
+
+ /**
+ * Decomposes an attribute value into a set of substring index keys.
+ *
+ * @param value The normalized attribute value
+ * @param modifiedKeys The map into which the modified
+ * keys will be inserted.
+ * @param insert <code>true</code> if generated keys should
+ * be inserted or <code>false</code> otherwise.
+ */
+ private void substringKeys(ByteString attValue,
+ Map<byte[], Boolean> modifiedKeys,
+ Boolean insert)
+ {
+ String value = attValue.stringValue();
+ int keyLength = subIndexer.gerSubstringLength();
+ for (int i = 0, remain = value.length(); remain > 0; i++, remain--)
+ {
+ int len = Math.min(keyLength, remain);
+ byte[] keyBytes = makeSubstringKey(value, i, len);
+ Boolean cinsert = modifiedKeys.get(keyBytes);
+ if (cinsert == null)
+ {
+ modifiedKeys.put(keyBytes, insert);
+ }
+ else if (!cinsert.equals(insert))
+ {
+ modifiedKeys.remove(keyBytes);
+ }
+ }
+ }
+
+
+
+ /**
+ * Makes a byte array representing a substring index key for
+ * one substring of a value.
+ *
+ * @param value The String containing the value.
+ * @param pos The starting position of the substring.
+ * @param len The length of the substring.
+ * @return A byte array containing a substring key.
+ */
+ private byte[] makeSubstringKey(String value, int pos, int len)
+ {
+ String sub = value.substring(pos, pos + len);
+ CollationKey col = collator.getCollationKey(sub);
+ byte[] origKey = col.toByteArray();
+ byte[] newKey = new byte[origKey.length - 4];
+ System.arraycopy(origKey, 0, newKey, 0, newKey.length);
+ return newKey;
+ }
+
+
+
+ /**
+ * Uses an equality index to retrieve the entry IDs that might contain a
+ * given initial substring.
+ * @param bytes A normalized initial substring of an attribute value.
+ * @return The candidate entry IDs.
+ */
+ private <T> T matchInitialSubstring(String value,
+ IndexQueryFactory<T> factory)
+ {
+ byte[] lower = makeSubstringKey(value, 0, value.length());
+ byte[] upper = new byte[lower.length];
+ System.arraycopy(lower, 0, upper, 0, lower.length);
+
+ for (int i = upper.length - 1; i >= 0; i--)
+ {
+ if (upper[i] == 0xFF)
+ {
+ // We have to carry the overflow to the more significant byte.
+ upper[i] = 0;
+ }
+ else
+ {
+ // No overflow, we can stop.
+ upper[i] = (byte) (upper[i] + 1);
+ break;
+ }
+ }
+ //Use the shared equality indexer.
+ return factory.createRangeMatchQuery(
+ indexer.getExtensibleIndexID(),
+ lower,
+ upper,
+ true,
+ false);
+ }
+
+
+
+ /**
+ * Retrieves the Index Records that might contain a given substring.
+ * @param value A String representing the attribute value.
+ * @param factory An IndexQueryFactory which issues calls to the backend.
+ * @param substrLength The length of the substring.
+ * @return The candidate entry IDs.
+ */
+ private <T> T matchSubstring(String value,
+ IndexQueryFactory<T> factory)
+ {
+ T intersectionQuery = null;
+ int substrLength = subIndexer.gerSubstringLength();
+
+ if (value.length() < substrLength)
+ {
+ byte[] lower = makeSubstringKey(value, 0, value.length());
+ byte[] upper = makeSubstringKey(value, 0, value.length());
+ for (int i = upper.length - 1; i >= 0; i--)
+ {
+ if (upper[i] == 0xFF)
+ {
+ // We have to carry the overflow to the more significant byte.
+ upper[i] = 0;
+ } else
+ {
+ // No overflow, we can stop.
+ upper[i] = (byte) (upper[i] + 1);
+ break;
+ }
+ }
+ // Read the range: lower <= keys < upper.
+ intersectionQuery =
+ factory.createRangeMatchQuery(
+ subIndexer.getExtensibleIndexID(),
+ lower,
+ upper,
+ true,
+ false);
+ }
+ else
+ {
+ List<T> queryList = new ArrayList<T>();
+ Set<byte[]> set =
+ new TreeSet<byte[]>(new AttributeIndex.KeyComparator());
+ for (int first = 0, last = substrLength;
+ last <= value.length(); first++, last++)
+ {
+ byte[] keyBytes;
+ keyBytes = makeSubstringKey(value, first, substrLength);
+ set.add(keyBytes);
+ }
+
+ for (byte[] keyBytes : set)
+ {
+ T single = factory.createExactMatchQuery(
+ subIndexer.getExtensibleIndexID(),
+ keyBytes);
+ queryList.add(single);
+ }
+ intersectionQuery =
+ factory.createIntersectionQuery(queryList);
+ }
+ return intersectionQuery;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> T createIndexQuery(ByteString assertionValue,
+ IndexQueryFactory<T> factory) throws DirectoryException
+ {
+ Assertion assertion = parseAssertion(assertionValue);
+ String subInitial = assertion.getInitial();
+ List<String> subAny = assertion.getAny();
+ String subFinal = assertion.getFinal();
+ List<T> queries = new ArrayList<T>();
+
+ if (subInitial == null && subAny.size() == 0 && subFinal == null)
+ {
+ //Can happen with a filter like "cn:en.6:=*".
+ //Just return an empty record.
+ return factory.createMatchAllQuery();
+ }
+ List<String> elements = new ArrayList<String>();
+ if (subInitial != null)
+ {
+ //Always use the shared indexer for initial match.
+ T query = matchInitialSubstring(subInitial, factory);
+ queries.add(query);
+ }
+
+ if (subAny != null && subAny.size() > 0)
+ {
+ elements.addAll(subAny);
+ }
+
+ if (subFinal != null)
+ {
+ elements.add(subFinal);
+ }
+
+
+ for (String element : elements)
+ {
+ queries.add(matchSubstring(element, factory));
+ }
+ return factory.createIntersectionQuery(queries);
+ }
}
- /**
- *Collation rule for less-than matching rule.
- */
- private final class CollationLessThanMatchingRule
- extends ExtensibleMatchingRule
+
+
+ /**
+ *An abstract Collation rule for Ordering matching rule.
+ */
+ private abstract class CollationOrderingMatchingRule
+ extends CollationMatchingRule
{
- //Names for this class.
- private final Collection<String> names;
+ /**
+ * Constructs a new CollationOrderingMatchingRule.
+ *
+ * @param nOID OID of the collation matching rule
+ * @param names names of this matching rule
+ * @param locale Locale of the collation matching rule
+ */
+ private CollationOrderingMatchingRule(String nOID,
+ Collection<String> names, Locale locale)
+ {
+ super(nOID,names,locale);
+ }
- //Collator for performing equality match.
- private final Collator collator;
- //Numeric OID of the rule.
- private final String nOID;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ByteString normalizeValue(ByteString value)
+ throws DirectoryException
+ {
+ CollationKey key = collator.getCollationKey(value.stringValue());
+ return new ASN1OctetString(key.toByteArray());
+ }
+
+
+
+ /**
+ * Compares the first value to the second and returns a value that
+ * indicates their relative order.
+ *
+ * @param b1 The normalized form of the first value to
+ * compare.
+ * @param b2 The normalized form of the second value to
+ * compare.
+ *
+ * @return A negative integer if {@code value1} should come before
+ * {@code value2} in ascending order, a positive integer if
+ * {@code value1} should come after {@code value2} in
+ * ascending order, or zero if there is no difference
+ * between the values with regard to ordering.
+ */
+ protected int compare(byte[] b1, byte[] b2) {
+ //Compare values using byte arrays.
+ int minLength = Math.min(b1.length, b2.length);
+
+ for (int i=0; i < minLength; i++)
+ {
+ int firstByte = 0xFF & ((int)b1[i]);
+ int secondByte = 0xFF & ((int)b2[i]);
+
+ if (firstByte == secondByte)
+ {
+ continue;
+ }
+ else if (firstByte < secondByte)
+ {
+ return -1;
+ }
+ else if (firstByte > secondByte)
+ {
+ return 1;
+ }
+ }
+
+ if (b1.length == b2.length)
+ {
+ return 0;
+ }
+ else if (b1.length < b2.length)
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ }
+
+ /**
+ * Collation matching rule for Less-than matching rule.
+ */
+ private final class CollationLessThanMatchingRule
+ extends CollationOrderingMatchingRule
+ {
/**
* Constructs a new CollationLessThanMatchingRule.
@@ -1293,160 +1763,24 @@
* @param locale Locale of the collation matching rule
*/
private CollationLessThanMatchingRule(String nOID,
- Collection<String> names,Locale locale)
+ Collection<String> names, Locale locale)
{
- super();
- this.names = names;
- this.collator =createCollator(locale);
- this.nOID = nOID;
+ super(nOID, names, locale);
}
- /**
- * {@inheritDoc}
- */
- @Override
- public String getName()
- {
- //Concatenate all the names and return.
- StringBuilder builder = new StringBuilder();
- for(String name: getAllNames())
- {
- builder.append(name);
- builder.append("\b");
- }
- return builder.toString();
- }
-
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Collection<String> getAllNames()
- {
- return Collections.unmodifiableCollection(names);
- }
-
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getOID()
- {
- return nOID;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getDescription()
- {
- // There is no standard description for this matching rule.
- return null;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getSyntaxOID()
- {
- return SYNTAX_DIRECTORY_STRING_OID;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ByteString normalizeValue(ByteString value)
- throws DirectoryException
- {
- CollationKey key = collator.getCollationKey(value.stringValue());
- return new ASN1OctetString(key.toByteArray());
- }
-
-
-
- /**
- * Compares the first value to the second and returns a value that
- * indicates their relative order.
- *
- * @param b1 The normalized form of the first value to
- * compare.
- * @param b2 The normalized form of the second value to
- * compare.
- *
- * @return A negative integer if {@code value1} should come before
- * {@code value2} in ascending order, a positive integer if
- * {@code value1} should come after {@code value2} in
- * ascending order, or zero if there is no difference
- * between the values with regard to ordering.
- */
- private int compare(byte[] b1, byte[] b2)
- {
- //Compare values using byte arrays.
- int minLength = Math.min(b1.length, b2.length);
-
- for (int i=0; i < minLength; i++)
- {
- int firstByte = 0xFF & ((int)b1[i]);
- int secondByte = 0xFF & ((int)b2[i]);
-
- if (firstByte == secondByte)
- {
- continue;
- }
- else if (firstByte < secondByte)
- {
- return -1;
- }
- else if (firstByte > secondByte)
- {
- return 1;
- }
- }
-
- if (b1.length == b2.length)
- {
- return 0;
- }
- else if (b1.length < b2.length)
- {
- return -1;
- }
- else
- {
- return 1;
- }
- }
-
-
-
/**
* {@inheritDoc}
*/
@Override
public ConditionResult valuesMatch(ByteString attributeValue,
- ByteString assertionValue)
+ ByteString assertionValue)
{
- int ret = compare(attributeValue.value(),assertionValue.value());
+ int ret = compare(attributeValue.value(), assertionValue.value());
- if(ret <0)
+ if (ret < 0)
{
return ConditionResult.TRUE;
}
@@ -1455,24 +1789,35 @@
return ConditionResult.FALSE;
}
}
+
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> T createIndexQuery(ByteString assertionValue,
+ IndexQueryFactory<T> factory) throws DirectoryException
+ {
+ byte[] lower = new byte[0];
+ byte[] upper = normalizeValue(assertionValue).value();
+ return factory.createRangeMatchQuery(indexer.getExtensibleIndexID(),
+ lower,
+ upper,
+ false,
+ false);
+ }
}
+
/**
- * Collation rule for less-than-equal-to matching rule.
- */
+ * Collation rule for less-than-equal-to matching rule.
+ */
private final class CollationLessThanOrEqualToMatchingRule
- extends ExtensibleMatchingRule
+ extends CollationOrderingMatchingRule
{
- //Names for this class.
- private final Collection<String> names;
-
- //Collator for performing equality match.
- private final Collator collator;
-
- //Numeric OID of the rule.
- private final String nOID;
-
/**
* Constructs a new CollationLessThanOrEqualToMatchingRule.
@@ -1482,161 +1827,25 @@
* @param locale Locale of the collation matching rule
*/
private CollationLessThanOrEqualToMatchingRule(String nOID,
- Collection<String> names,
- Locale locale)
+ Collection<String> names,
+ Locale locale)
{
- super();
- this.names = names;
- this.collator =createCollator(locale);
- this.nOID = nOID;
+ super(nOID, names, locale);
}
- /**
- * {@inheritDoc}
- */
- @Override
- public String getName()
- {
- //Concatenate all the names and return.
- StringBuilder builder = new StringBuilder();
- for(String name: getAllNames())
- {
- builder.append(name);
- builder.append("\b");
- }
- return builder.toString();
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Collection<String> getAllNames()
- {
- return Collections.unmodifiableCollection(names);
- }
-
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getOID()
- {
- return nOID;
- }
-
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getDescription()
- {
- // There is no standard description for this matching rule.
- return null;
- }
-
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getSyntaxOID()
- {
- return SYNTAX_DIRECTORY_STRING_OID;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ByteString normalizeValue(ByteString value)
- throws DirectoryException
- {
- CollationKey key = collator.getCollationKey(value.stringValue());
- return new ASN1OctetString(key.toByteArray());
- }
-
-
-
- /**
- * Compares the first value to the second and returns a value that
- * indicates their relative order.
- *
- * @param b1 The normalized form of the first value to
- * compare.
- * @param b2 The normalized form of the second value to
- * compare.
- *
- * @return A negative integer if {@code value1} should come before
- * {@code value2} in ascending order, a positive integer if
- * {@code value1} should come after {@code value2} in
- * ascending order, or zero if there is no difference
- * between the values with regard to ordering.
- */
- public int compare(byte[] b1, byte[] b2)
- {
- //Compare values using byte arrays.
- int minLength = Math.min(b1.length, b2.length);
-
- for (int i=0; i < minLength; i++)
- {
- int firstByte = 0xFF & ((int)b1[i]);
- int secondByte = 0xFF & ((int)b2[i]);
-
- if (firstByte == secondByte)
- {
- continue;
- }
- else if (firstByte < secondByte)
- {
- return -1;
- }
- else if (firstByte > secondByte)
- {
- return 1;
- }
- }
-
- if (b1.length == b2.length)
- {
- return 0;
- }
- else if (b1.length < b2.length)
- {
- return -1;
- }
- else
- {
- return 1;
- }
- }
-
-
/**
* {@inheritDoc}
*/
@Override
public ConditionResult valuesMatch(ByteString attributeValue,
- ByteString assertionValue)
+ ByteString assertionValue)
{
- int ret = compare(attributeValue.value(),assertionValue.value());
+ int ret = compare(attributeValue.value(), assertionValue.value());
- if(ret <= 0)
+ if (ret <= 0)
{
return ConditionResult.TRUE;
}
@@ -1645,25 +1854,37 @@
return ConditionResult.FALSE;
}
}
+
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> T createIndexQuery(ByteString assertionValue,
+ IndexQueryFactory<T> factory)
+ throws DirectoryException
+ {
+ byte[] lower = new byte[0];
+ byte[] upper = normalizeValue(assertionValue).value();
+ // Read the range: lower < keys <= upper.
+ return factory.createRangeMatchQuery(indexer.getExtensibleIndexID(),
+ lower,
+ upper,
+ false,
+ true);
+ }
}
- /**
- * Collation rule for greater-than matching rule.
- */
+ /**
+ * Collation rule for greater-than matching rule.
+ */
private final class CollationGreaterThanMatchingRule
- extends ExtensibleMatchingRule
+ extends CollationOrderingMatchingRule
{
- //Names for this class.
- private final Collection<String> names;
-
- //Collator for performing equality match.
- private final Collator collator;
-
- //Numeric OID of the rule.
- private final String nOID;
-
/**
* Constructs a new CollationGreaterThanMatchingRule.
@@ -1673,147 +1894,9 @@
* @param locale Locale of the collation matching rule
*/
private CollationGreaterThanMatchingRule(String nOID,
- Collection<String> names,Locale locale)
+ Collection<String> names, Locale locale)
{
- super();
- this.names = names;
- this.collator =createCollator(locale);
- this.nOID = nOID;
- }
-
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getName()
- {
- //Concatenate all the names and return.
- StringBuilder builder = new StringBuilder();
- for(String name: getAllNames())
- {
- builder.append(name);
- builder.append("\b");
- }
- return builder.toString();
- }
-
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Collection<String> getAllNames()
- {
- return Collections.unmodifiableCollection(names);
- }
-
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getOID()
- {
- return nOID;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getDescription()
- {
- // There is no standard description for this matching rule.
- return null;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getSyntaxOID()
- {
- return SYNTAX_DIRECTORY_STRING_OID;
- }
-
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ByteString normalizeValue(ByteString value)
- throws DirectoryException
- {
- CollationKey key = collator.getCollationKey(value.stringValue());
- return new ASN1OctetString(key.toByteArray());
- }
-
-
-
- /**
- * Compares the first value to the second and returns a value that
- * indicates their relative order.
- *
- * @param b1 The normalized form of the first value to
- * compare.
- * @param b2 The normalized form of the second value to
- * compare.
- *
- * @return A negative integer if {@code value1} should come before
- * {@code value2} in ascending order, a positive integer if
- * {@code value1} should come after {@code value2} in
- * ascending order, or zero if there is no difference
- * between the values with regard to ordering.
- */
- public int compare(byte[] b1, byte[] b2)
- {
- //Compare values using byte arrays.
- int minLength = Math.min(b1.length, b2.length);
-
- for (int i=0; i < minLength; i++)
- {
- int firstByte = 0xFF & ((int)b1[i]);
- int secondByte = 0xFF & ((int)b2[i]);
-
- if (firstByte == secondByte)
- {
- continue;
- }
- else if (firstByte < secondByte)
- {
- return -1;
- }
- else if (firstByte > secondByte)
- {
- return 1;
- }
- }
-
- if (b1.length == b2.length)
- {
- return 0;
- }
- else if (b1.length < b2.length)
- {
- return -1;
- }
- else
- {
- return 1;
- }
+ super(nOID, names, locale);
}
@@ -1823,39 +1906,45 @@
*/
@Override
public ConditionResult valuesMatch(ByteString attributeValue,
- ByteString assertionValue)
+ ByteString assertionValue)
{
- int ret = compare(attributeValue.value(),assertionValue.value());
+ int ret = compare(attributeValue.value(), assertionValue.value());
- if(ret > 0)
- {
+ if (ret > 0) {
return ConditionResult.TRUE;
- }
- else
- {
+ } else {
return ConditionResult.FALSE;
}
}
+
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> T createIndexQuery(ByteString assertionValue,
+ IndexQueryFactory<T> factory)
+ throws DirectoryException
+ {
+ byte[] lower = normalizeValue(assertionValue).value();
+ byte[] upper = new byte[0];
+ return factory.createRangeMatchQuery(indexer.getExtensibleIndexID(),
+ lower,
+ upper,
+ false,
+ false);
+ }
}
-
- /**
- * Collation rule for greater-than-equal-to matching rule.
- */
+ /**
+ * Collation rule for greater-than-equal-to matching rule.
+ */
private final class CollationGreaterThanOrEqualToMatchingRule
- extends ExtensibleMatchingRule
+ extends CollationOrderingMatchingRule
{
- //Names for this class.
- private final Collection<String> names;
-
- //Collator for performing equality match.
- private final Collator collator;
-
- //Numeric OID of the rule.
- private final String nOID;
-
-
/**
* Constructs a new CollationGreaterThanOrEqualToMatchingRule.
*
@@ -1864,143 +1953,31 @@
* @param locale Locale of the collation matching rule
*/
private CollationGreaterThanOrEqualToMatchingRule(String nOID,
- Collection<String> names,
- Locale locale)
+ Collection<String> names,
+ Locale locale)
{
- super();
- this.names = names;
- this.collator =createCollator(locale);
- this.nOID = nOID;
+ super(nOID, names, locale);
}
- /**
- * {@inheritDoc}
- */
+
+ /**
+ * {@inheritDoc}
+ */
@Override
- public String getName()
+ public ConditionResult valuesMatch(ByteString attributeValue,
+ ByteString assertionValue)
{
- //Concatenate all the names and return.
- StringBuilder builder = new StringBuilder();
- for(String name: getAllNames())
+ int ret = compare(attributeValue.value(),assertionValue.value());
+
+ if (ret >= 0)
{
- builder.append(name);
- builder.append("\b");
- }
- return builder.toString();
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Collection<String> getAllNames()
- {
- return Collections.unmodifiableCollection(names);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getOID()
- {
- return nOID;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getDescription()
- {
- // There is no standard description for this matching rule.
- return null;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getSyntaxOID()
- {
- return SYNTAX_DIRECTORY_STRING_OID;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ByteString normalizeValue(ByteString value)
- throws DirectoryException
- {
- CollationKey key = collator.getCollationKey(value.stringValue());
- return new ASN1OctetString(key.toByteArray());
- }
-
-
-
- /**
- * Compares the first value to the second and returns a value that
- * indicates their relative order.
- *
- * @param b1 The normalized form of the first value to
- * compare.
- * @param b2 The normalized form of the second value to
- * compare.
- *
- * @return A negative integer if {@code value1} should come before
- * {@code value2} in ascending order, a positive integer if
- * {@code value1} should come after {@code value2} in
- * ascending order, or zero if there is no difference
- * between the values with regard to ordering.
- */
- public int compare(byte[] b1, byte[] b2)
- {
- //Compare values using byte arrays.
- int minLength = Math.min(b1.length, b2.length);
-
- for (int i=0; i < minLength; i++)
- {
- int firstByte = 0xFF & ((int)b1[i]);
- int secondByte = 0xFF & ((int)b2[i]);
-
- if (firstByte == secondByte)
- {
- continue;
- }
- else if (firstByte < secondByte)
- {
- return -1;
- }
- else if (firstByte > secondByte)
- {
- return 1;
- }
- }
-
- if (b1.length == b2.length)
- {
- return 0;
- }
- else if (b1.length < b2.length)
- {
- return -1;
+ return ConditionResult.TRUE;
}
else
{
- return 1;
+ return ConditionResult.FALSE;
}
}
@@ -2010,27 +1987,228 @@
* {@inheritDoc}
*/
@Override
- public ConditionResult valuesMatch(ByteString attributeValue,
- ByteString assertionValue)
+ public <T> T createIndexQuery(ByteString assertionValue,
+ IndexQueryFactory<T> factory)
+ throws DirectoryException
{
- int ret = compare(attributeValue.value(),assertionValue.value());
-
- if(ret >= 0)
- {
- return ConditionResult.TRUE;
- }
- else
- {
- return ConditionResult.FALSE;
- }
+ byte[] lower = normalizeValue(assertionValue).value();
+ byte[] upper = new byte[0];
+ // Read the range: lower <= keys < upper.
+ return factory.createRangeMatchQuery(indexer.getExtensibleIndexID(),
+ lower,
+ upper,
+ true,
+ false);
}
}
- /**
- * A utility class for extracting the OID and Language Tag from the
- * configuration entry.
- */
+ /**
+ * Extensible Indexer class for Collation Matching rules which share the
+ * same index. This Indexer is shared by Equality and Ordering Collation
+ * Matching Rules.
+ */
+ private final class CollationSharedExtensibleIndexer
+ extends ExtensibleIndexer
+ {
+
+ /**
+ * The Extensible Matching Rule.
+ */
+ private final CollationMatchingRule matchingRule;
+
+
+
+ /**
+ * Creates a new instance of CollationSharedExtensibleIndexer.
+ *
+ * @param matchingRule The Collation Matching Rule.
+ */
+ private CollationSharedExtensibleIndexer(
+ CollationMatchingRule matchingRule)
+ {
+ this.matchingRule = matchingRule;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getExtensibleIndexID()
+ {
+ return EXTENSIBLE_INDEXER_ID_SHARED;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final void getKeys(AttributeValue value,
+ Set<byte[]> keys)
+ {
+ ByteString key;
+ try
+ {
+ key = matchingRule.normalizeValue(value.getValue());
+ keys.add(key.value());
+ }
+ catch (DirectoryException de)
+ {
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final void getKeys(AttributeValue value,
+ Map<byte[], Boolean> modifiedKeys,
+ Boolean insert)
+ {
+ Set<byte[]> keys = new HashSet<byte[]>();
+ getKeys(value, keys);
+ for (byte[] key : keys)
+ {
+ Boolean cInsert = modifiedKeys.get(key);
+ if (cInsert == null)
+ {
+ modifiedKeys.put(key, insert);
+ }
+ else if (!cInsert.equals(insert))
+ {
+ modifiedKeys.remove(key);
+ }
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getPreferredIndexName()
+ {
+ return matchingRule.getIndexName();
+ }
+ }
+
+ /**
+ * Extensible Indexer class for Collation Substring Matching rules.
+ * This Indexer is used by Substring Collation Matching Rules.
+ */
+ private final class CollationSubstringExtensibleIndexer
+ extends ExtensibleIndexer
+ {
+ //The CollationSubstringMatching Rule.
+ private final CollationSubstringMatchingRule matchingRule;
+
+
+
+ //The substring length.
+ private int substringLen;
+
+
+
+ /**
+ * Creates a new instance of CollationSubstringExtensibleIndexer.
+ *
+ * @param matchingRule The CollationSubstringMatching Rule.
+ * @param substringLen The substring length.
+ */
+ private CollationSubstringExtensibleIndexer(
+ CollationSubstringMatchingRule matchingRule,
+ int substringLen)
+ {
+ this.matchingRule = matchingRule;
+ this.substringLen = substringLen;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void getKeys(AttributeValue value,
+ Set<byte[]> keys)
+ {
+ matchingRule.subtringKeys(value.getValue(),
+ keys);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void getKeys(AttributeValue attValue,
+ Map<byte[], Boolean> modifiedKeys,
+ Boolean insert)
+ {
+ matchingRule.substringKeys(attValue.getValue(),
+ modifiedKeys,
+ insert);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getPreferredIndexName()
+ {
+ return matchingRule.getIndexName();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getExtensibleIndexID()
+ {
+ return EXTENSIBLE_INDEXER_ID_SUBSTRING;
+ }
+
+
+
+ /**
+ * Returns the substring length.
+ * @return The length of the substring.
+ */
+ private int gerSubstringLength()
+ {
+ return substringLen;
+ }
+
+
+
+ /**
+ * Sets the substring length.
+ * @param substringLen The substring length.
+ */
+ private void setSubstringLength(int substringLen)
+ {
+ this.substringLen = substringLen;
+ }
+ }
+
+
+
+ /**
+ * A utility class for extracting the OID and Language Tag from the
+ * configuration entry.
+ */
private final class CollationMapper
{
//OID of the collation rule.
--
Gitblit v1.10.0