Checkpoint commit for OPENDJ-1308 Migrate schema support
Align SubstringMatchingRule class on the SDK
* Update MatchingRule interface to match SDK equivalent class
** Add getSubstringAssertion() method
* Implement getSubstringAssertion() in AbstractMatchingRule and SubstringMatchingRule
classes
* Use Assertions instead of valueMathcesSubstring() and normalizeSubstring() methods
when using a SubstringMatchingRule
* Add XX:MaxPermSize argument with value:128M when running tests to avoid OOM
| | |
| | | |
| | | <!-- Build JVM properties --> |
| | | <property name="MEM" value="512M"/> |
| | | <property name="PERMSIZE" value="128M"/> |
| | | |
| | | <!-- Build OpenDMK properties --> |
| | | <property file="build.properties"/> |
| | |
| | | <jvmarg value="-Dtest.progress=${test.progress}" /> |
| | | <jvmarg value="-Xms${MEM}" /> |
| | | <jvmarg value="-Xmx${MEM}" /> |
| | | <jvmarg value="-XX:MaxPermSize=${PERMSIZE}" /> |
| | | <jvmarg value="${jvm.debug.arg1}" /> |
| | | <jvmarg value="${jvm.debug.arg2}" /> |
| | | <jvmarg value="${jvm.debug.arg3}" /> |
| | |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.opendj.ldap.Assertion; |
| | | import org.forgerock.opendj.ldap.ByteSequence; |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Assertion getSubstringAssertion(ByteSequence subInitial, |
| | | List<? extends ByteSequence> subAnyElements, ByteSequence subFinal) throws DecodeException |
| | | { |
| | | return UNDEFINED_ASSERTION; |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isObsolete() |
| | | { |
| | | return false; |
| | |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.opendj.ldap.Assertion; |
| | | import org.forgerock.opendj.ldap.ByteSequence; |
| | |
| | | public Assertion getLessOrEqualAssertion(final ByteSequence assertionValue) throws DecodeException; |
| | | |
| | | /** |
| | | * Returns the normalized form of the provided assertion substring values, |
| | | * which is best suited for efficiently performing matching operations on |
| | | * that value. |
| | | * |
| | | * @param subInitial |
| | | * The normalized substring value fragment that should appear at |
| | | * the beginning of the target value. |
| | | * @param subAnyElements |
| | | * The normalized substring value fragments that should appear in |
| | | * the middle of the target value. |
| | | * @param subFinal |
| | | * The normalized substring value fragment that should appear at |
| | | * the end of the target value. |
| | | * @return The normalized version of the provided assertion value. |
| | | * @throws DecodeException |
| | | * if the syntax of the value is not valid. |
| | | */ |
| | | public Assertion getSubstringAssertion(final ByteSequence subInitial, |
| | | final List<? extends ByteSequence> subAnyElements, final ByteSequence subFinal) throws DecodeException; |
| | | |
| | | /** |
| | | * Indicates whether this matching rule is declared "OBSOLETE". The |
| | | * default implementation will always return {@code false}. If that |
| | | * is not acceptable for a particular matching rule implementation, |
| | |
| | | */ |
| | | package org.opends.server.api; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.TreeSet; |
| | | |
| | | import org.forgerock.opendj.ldap.Assertion; |
| | | import org.forgerock.opendj.ldap.ByteSequence; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | 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; |
| | | |
| | | /** |
| | | * This class defines the set of methods and structures that must be |
| | |
| | | |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 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; |
| | | |
| | | 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 normalizedAttributeValue) { |
| | | final int valueLength = normalizedAttributeValue.length(); |
| | | |
| | | int pos = 0; |
| | | if (normInitial != null) { |
| | | final int initialLength = normInitial.length(); |
| | | if (initialLength > valueLength) { |
| | | return ConditionResult.FALSE; |
| | | } |
| | | |
| | | for (; pos < initialLength; pos++) { |
| | | if (normInitial.byteAt(pos) != normalizedAttributeValue.byteAt(pos)) { |
| | | return ConditionResult.FALSE; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (normAnys != null) { |
| | | matchEachSubstring: |
| | | for (final ByteSequence element : normAnys) { |
| | | final int anyLength = element.length(); |
| | | final int end = valueLength - anyLength; |
| | | matchCurrentSubstring: |
| | | for (; pos <= end; pos++) { |
| | | // Try to match all characters from the substring |
| | | for (int i = 0; i < anyLength; i++) { |
| | | if (element.byteAt(i) != normalizedAttributeValue.byteAt(pos + i)) { |
| | | // not a match, |
| | | // try to find a match in the rest of this value |
| | | continue matchCurrentSubstring; |
| | | } |
| | | } |
| | | // we just matched current substring, |
| | | // go try to match the next substring |
| | | pos += anyLength; |
| | | continue matchEachSubstring; |
| | | } |
| | | // Could not match current substring |
| | | return ConditionResult.FALSE; |
| | | } |
| | | } |
| | | |
| | | if (normFinal != null) { |
| | | final int finalLength = normFinal.length(); |
| | | |
| | | if (valueLength - finalLength < pos) { |
| | | return ConditionResult.FALSE; |
| | | } |
| | | |
| | | pos = valueLength - finalLength; |
| | | for (int i = 0; i < finalLength; i++, pos++) { |
| | | if (normFinal.byteAt(i) != normalizedAttributeValue.byteAt(pos)) { |
| | | return ConditionResult.FALSE; |
| | | } |
| | | } |
| | | } |
| | | |
| | | 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) == (byte) 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)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // TODO : reminder : should add this method in the SDK |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public int hashCode() |
| | | { |
| | | int hashCode = 0; |
| | | if (normInitial != null) |
| | | { |
| | | hashCode += normInitial.hashCode(); |
| | | } |
| | | if (normAnys != null) |
| | | { |
| | | for (ByteString any : normAnys) |
| | | { |
| | | hashCode += any.hashCode(); |
| | | } |
| | | } |
| | | if (normFinal != null) |
| | | { |
| | | hashCode += normFinal.hashCode(); |
| | | } |
| | | return hashCode; |
| | | } |
| | | |
| | | // TODO : reminder : should add this method in the SDK |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean equals(Object obj) |
| | | { |
| | | if (obj == this) |
| | | { |
| | | return true; |
| | | } |
| | | if (! (obj instanceof DefaultSubstringAssertion)) |
| | | { |
| | | return false; |
| | | } |
| | | DefaultSubstringAssertion other = (DefaultSubstringAssertion) obj; |
| | | boolean initialCheck = normInitial == null ? other.normInitial == null : normInitial.equals(other.normInitial); |
| | | if (!initialCheck) |
| | | { |
| | | return false; |
| | | } |
| | | boolean finalCheck = normFinal == null ? other.normFinal == null : normFinal.equals(other.normFinal); |
| | | if (!finalCheck) |
| | | { |
| | | return false; |
| | | } |
| | | boolean anyCheck = normAnys == null ? other.normAnys == null : normAnys.length == other.normAnys.length; |
| | | if (!anyCheck) |
| | | { |
| | | return false; |
| | | } |
| | | if (normAnys != null) |
| | | { |
| | | for (int i = 0; i < normAnys.length; i++) |
| | | { |
| | | if (! normAnys[i].equals(other.normAnys[i])) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Assertion getSubstringAssertion(ByteSequence subInitial, |
| | | List<? extends ByteSequence> subAnyElements, ByteSequence subFinal) |
| | | throws DecodeException |
| | | { |
| | | final ByteString normInitial = subInitial == null ? null : normalizeSubstring(subInitial); |
| | | |
| | | ByteString[] normAnys = null; |
| | | if (subAnyElements != null && !subAnyElements.isEmpty()) |
| | | { |
| | | normAnys = new ByteString[subAnyElements.size()]; |
| | | for (int i = 0; i < subAnyElements.size(); i++) |
| | | { |
| | | normAnys[i] = normalizeSubstring(subAnyElements.get(i)); |
| | | } |
| | | } |
| | | final ByteString normFinal = subFinal == null ? null : normalizeSubstring(subFinal); |
| | | |
| | | return new DefaultSubstringAssertion(normInitial, normAnys, normFinal); |
| | | } |
| | | |
| | | } |
| | | |
| | |
| | | */ |
| | | package org.opends.server.api; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | | import org.forgerock.opendj.config.server.ConfigException; |
| | | 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.opends.server.admin.std.server.VirtualAttributeCfg; |
| | | import org.opends.server.core.SearchOperation; |
| | | import org.opends.server.types.Attribute; |
| | |
| | | List<ByteString> subAny, |
| | | ByteString subFinal) |
| | | { |
| | | SubstringMatchingRule matchingRule = |
| | | rule.getAttributeType().getSubstringMatchingRule(); |
| | | MatchingRule matchingRule = rule.getAttributeType().getSubstringMatchingRule(); |
| | | if (matchingRule == null) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | ByteString normalizedSubInitial; |
| | | if (subInitial == null) |
| | | Assertion assertion; |
| | | try |
| | | { |
| | | normalizedSubInitial = null; |
| | | assertion = matchingRule.getSubstringAssertion(subInitial, subAny, subFinal); |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | normalizedSubInitial = |
| | | matchingRule.normalizeSubstring(subInitial); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | logger.traceException(e); |
| | | |
| | | // The substring couldn't be normalized => return "undefined". |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | catch(DecodeException e) { |
| | | logger.traceException(e); |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | ArrayList<ByteSequence> normalizedSubAny; |
| | | if (subAny == null) |
| | | { |
| | | normalizedSubAny = null; |
| | | } |
| | | else |
| | | { |
| | | normalizedSubAny = |
| | | new ArrayList<ByteSequence>(subAny.size()); |
| | | for (ByteString subAnyElement : subAny) |
| | | { |
| | | try |
| | | { |
| | | normalizedSubAny.add(matchingRule.normalizeSubstring( |
| | | subAnyElement)); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | logger.traceException(e); |
| | | |
| | | // The substring couldn't be normalized => return "undefined". |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | ByteString normalizedSubFinal; |
| | | if (subFinal == null) |
| | | { |
| | | normalizedSubFinal = null; |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | normalizedSubFinal = |
| | | matchingRule.normalizeSubstring(subFinal); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | logger.traceException(e); |
| | | |
| | | // The substring couldn't be normalized => return "undefined". |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | |
| | | |
| | | ConditionResult result = ConditionResult.FALSE; |
| | | for (ByteString value : getValues(entry, rule)) |
| | | { |
| | | try |
| | | { |
| | | ByteString nv = matchingRule.normalizeAttributeValue(value); |
| | | if (matchingRule.valueMatchesSubstring( |
| | | nv, |
| | | normalizedSubInitial, |
| | | normalizedSubAny, |
| | | normalizedSubFinal)) |
| | | if (assertion.matches(matchingRule.normalizeAttributeValue(value)).toBoolean()) |
| | | { |
| | | return ConditionResult.TRUE; |
| | | } |
| | |
| | | import org.forgerock.opendj.io.ASN1Reader; |
| | | import org.forgerock.opendj.io.ASN1Writer; |
| | | import org.forgerock.opendj.ldap.Assertion; |
| | | import org.forgerock.opendj.ldap.ByteSequence; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.DecodeException; |
| | | import org.forgerock.util.Reject; |
| | |
| | | // The approximate matching rule for this matched values filter. |
| | | private MatchingRule approximateMatchingRule; |
| | | |
| | | // The normalized subFinal value for this matched values filter. |
| | | private ByteString normalizedSubFinal; |
| | | |
| | | // The normalized subInitial value for this matched values filter. |
| | | private ByteString normalizedSubInitial; |
| | | |
| | | // The raw, unprocessed assertion value for this matched values filter. |
| | | private final ByteString rawAssertionValue; |
| | | |
| | |
| | | // The equality matching rule for this matched values filter. |
| | | private MatchingRule equalityMatchingRule; |
| | | |
| | | // The set of normalized subAny values for this matched values filter. |
| | | private List<ByteString> normalizedSubAny; |
| | | |
| | | // The set of subAny values for this matched values filter. |
| | | private final List<ByteString> subAny; |
| | | |
| | |
| | | // The substring matching rule for this matched values filter. |
| | | private SubstringMatchingRule substringMatchingRule; |
| | | |
| | | |
| | | /** |
| | | * The assertion created from substring matching rule using values of this |
| | | * filter. |
| | | */ |
| | | private Assertion substringAssertion; |
| | | |
| | | /** |
| | | * Creates a new matched values filter with the provided information. |
| | |
| | | this.subAny = subAny; |
| | | this.subFinal = subFinal; |
| | | this.matchingRuleID = matchingRuleID; |
| | | |
| | | decoded = false; |
| | | attributeType = null; |
| | | assertionValue = null; |
| | | matchingRule = null; |
| | | normalizedSubInitial = null; |
| | | normalizedSubAny = null; |
| | | normalizedSubFinal = null; |
| | | approximateMatchingRule = null; |
| | | equalityMatchingRule = null; |
| | | orderingMatchingRule = null; |
| | | substringMatchingRule = null; |
| | | } |
| | | |
| | | |
| | |
| | | return subInitial; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the normalized form of the subInitial element. |
| | | * |
| | | * @return The normalized form of the subInitial element, or |
| | | * <CODE>null</CODE> if there is none. |
| | | */ |
| | | public ByteString getNormalizedSubInitialElement() |
| | | { |
| | | if (normalizedSubInitial == null) |
| | | private Assertion getSubstringAssertion() { |
| | | if (substringAssertion == null) |
| | | { |
| | | if ((subInitial != null) && (getSubstringMatchingRule() != null)) |
| | | try |
| | | { |
| | | try |
| | | { |
| | | normalizedSubInitial = |
| | | getSubstringMatchingRule().normalizeSubstring(subInitial); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | logger.traceException(e); |
| | | } |
| | | substringAssertion = |
| | | getSubstringMatchingRule().getSubstringAssertion(subInitial, subAny, subFinal); |
| | | } |
| | | catch (DecodeException e) |
| | | { |
| | | logger.traceException(e); |
| | | } |
| | | } |
| | | |
| | | return normalizedSubInitial; |
| | | return substringAssertion; |
| | | } |
| | | |
| | | |
| | |
| | | return subAny; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of normalized subAny elements for this matched values |
| | | * filter. |
| | | * |
| | | * @return The set of subAny elements for this matched values filter. If |
| | | * there are none, then an empty list will be returned. If a |
| | | * problem occurs while attempting to perform the normalization, then |
| | | * <CODE>null</CODE> will be returned. |
| | | */ |
| | | public List<ByteString> getNormalizedSubAnyElements() |
| | | { |
| | | if (normalizedSubAny == null) |
| | | { |
| | | if ((subAny == null) || (subAny.isEmpty())) |
| | | { |
| | | normalizedSubAny = new ArrayList<ByteString>(0); |
| | | } |
| | | else |
| | | { |
| | | if (getSubstringMatchingRule() == null) |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | normalizedSubAny = new ArrayList<ByteString>(); |
| | | try |
| | | { |
| | | for (ByteString s : subAny) |
| | | { |
| | | normalizedSubAny.add( |
| | | substringMatchingRule.normalizeSubstring(s)); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | logger.traceException(e); |
| | | |
| | | normalizedSubAny = null; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return normalizedSubAny; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the subFinal element for this matched values filter. |
| | | * |
| | |
| | | return subFinal; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the normalized form of the subFinal element. |
| | | * |
| | | * @return The normalized form of the subFinal element, or <CODE>null</CODE> |
| | | * if there is none. |
| | | */ |
| | | public ByteString getNormalizedSubFinalElement() |
| | | { |
| | | if (normalizedSubFinal == null) |
| | | { |
| | | if ((subFinal != null) && (getSubstringMatchingRule() != null)) |
| | | { |
| | | try |
| | | { |
| | | normalizedSubFinal = |
| | | getSubstringMatchingRule().normalizeSubstring(subFinal); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | logger.traceException(e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return normalizedSubFinal; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the matching rule ID for this matched values filter. |
| | | * |
| | |
| | | { |
| | | getAttributeType(); |
| | | getAssertionValue(); |
| | | getNormalizedSubInitialElement(); |
| | | getNormalizedSubAnyElements(); |
| | | getNormalizedSubFinalElement(); |
| | | getSubstringAssertion(); |
| | | getMatchingRule(); |
| | | getApproximateMatchingRule(); |
| | | getEqualityMatchingRule(); |
| | |
| | | case SUBSTRINGS_TYPE: |
| | | if (attributeType != null |
| | | && attributeType.equals(type) |
| | | && substringMatchingRule != null) |
| | | && substringAssertion != null) |
| | | { |
| | | try |
| | | { |
| | | ArrayList<ByteSequence> normalizedSubAnyBS = |
| | | new ArrayList<ByteSequence>(normalizedSubAny); |
| | | return substringMatchingRule.valueMatchesSubstring( |
| | | substringMatchingRule.normalizeAttributeValue(value), |
| | | normalizedSubInitial, normalizedSubAnyBS, normalizedSubFinal); |
| | | return substringAssertion.matches(substringMatchingRule.normalizeAttributeValue(value)).toBoolean(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | |
| | | package org.opends.server.types; |
| | | |
| | | import java.util.AbstractSet; |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.Iterator; |
| | |
| | | |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | | 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; |
| | |
| | | ByteString subInitial, |
| | | List<ByteString> subAny, ByteString subFinal) |
| | | { |
| | | SubstringMatchingRule matchingRule = attributeType |
| | | .getSubstringMatchingRule(); |
| | | SubstringMatchingRule matchingRule = attributeType.getSubstringMatchingRule(); |
| | | if (matchingRule == null) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | ByteString normalizedSubInitial; |
| | | if (subInitial == null) |
| | | { |
| | | normalizedSubInitial = null; |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | normalizedSubInitial = |
| | | matchingRule.normalizeSubstring(subInitial); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | logger.traceException(e); |
| | | |
| | | // The substring couldn't be normalized. We have to return |
| | | // "undefined". |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | |
| | | ArrayList<ByteSequence> normalizedSubAny; |
| | | if (subAny == null) |
| | | Assertion assertion; |
| | | try |
| | | { |
| | | normalizedSubAny = null; |
| | | assertion = matchingRule.getSubstringAssertion(subInitial, subAny, subFinal); |
| | | } |
| | | else |
| | | catch (DecodeException e) |
| | | { |
| | | normalizedSubAny = new ArrayList<ByteSequence>(subAny.size()); |
| | | for (ByteString subAnyElement : subAny) |
| | | { |
| | | try |
| | | { |
| | | normalizedSubAny |
| | | .add(matchingRule.normalizeSubstring(subAnyElement)); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | logger.traceException(e); |
| | | |
| | | // The substring couldn't be normalized. We have to return |
| | | // "undefined". |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | } |
| | | |
| | | ByteString normalizedSubFinal; |
| | | if (subFinal == null) |
| | | { |
| | | normalizedSubFinal = null; |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | normalizedSubFinal = |
| | | matchingRule.normalizeSubstring(subFinal); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | logger.traceException(e); |
| | | |
| | | // The substring couldn't be normalized. We have to return |
| | | // "undefined". |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | logger.traceException(e); |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | ConditionResult result = ConditionResult.FALSE; |
| | |
| | | { |
| | | try |
| | | { |
| | | if (matchingRule.valueMatchesSubstring( |
| | | matchingRule.normalizeAttributeValue(value), |
| | | normalizedSubInitial, |
| | | normalizedSubAny, |
| | | normalizedSubFinal)) |
| | | if (assertion.matches(matchingRule.normalizeAttributeValue(value)).toBoolean()) |
| | | { |
| | | return ConditionResult.TRUE; |
| | | } |
| | |
| | | { |
| | | case AND: |
| | | case OR: |
| | | if (filterComponents.size() != f.filterComponents.size()) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | outerComponentLoop: |
| | | for (SearchFilter outerFilter : filterComponents) |
| | | { |
| | | for (SearchFilter innerFilter : f.filterComponents) |
| | | { |
| | | if (outerFilter.equals(innerFilter)) |
| | | { |
| | | continue outerComponentLoop; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | return true; |
| | | return andOrEqual(f); |
| | | case NOT: |
| | | return notComponent.equals(f.notComponent); |
| | | case EQUALITY: |
| | | return typeAndOptionsAndAssertionEqual(f); |
| | | case SUBSTRING: |
| | | return equalsSubstring(f); |
| | | return substringEqual(f); |
| | | case GREATER_OR_EQUAL: |
| | | return typeAndOptionsAndAssertionEqual(f); |
| | | case LESS_OR_EQUAL: |
| | |
| | | } |
| | | } |
| | | |
| | | private boolean andOrEqual(SearchFilter f) |
| | | { |
| | | if (filterComponents.size() != f.filterComponents.size()) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | outerComponentLoop: |
| | | for (SearchFilter outerFilter : filterComponents) |
| | | { |
| | | for (SearchFilter innerFilter : f.filterComponents) |
| | | { |
| | | if (outerFilter.equals(innerFilter)) |
| | | { |
| | | continue outerComponentLoop; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |
| | | private boolean typeAndOptionsAndAssertionEqual(SearchFilter f) |
| | | { |
| | |
| | | } |
| | | |
| | | |
| | | private boolean equalsSubstring(SearchFilter f) |
| | | private boolean substringEqual(SearchFilter f) |
| | | { |
| | | if (! attributeType.equals(f.attributeType)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | SubstringMatchingRule smr = |
| | | attributeType.getSubstringMatchingRule(); |
| | | if (smr == null) |
| | | SubstringMatchingRule rule = attributeType.getSubstringMatchingRule(); |
| | | if (rule == null) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | if (! optionsEqual(attributeOptions, f.attributeOptions)) |
| | | try |
| | | { |
| | | Assertion thisAssertion = rule.getSubstringAssertion(subInitialElement, subAnyElements, subFinalElement); |
| | | Assertion thatAssertion = rule.getSubstringAssertion(f.subInitialElement, f.subAnyElements, f.subFinalElement); |
| | | return thisAssertion.equals(thatAssertion); |
| | | } |
| | | catch (DecodeException e) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | if (subInitialElement == null) |
| | | { |
| | | if (f.subInitialElement != null) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (f.subInitialElement == null) |
| | | { |
| | | return false; |
| | | } |
| | | try |
| | | { |
| | | ByteString nSI1 = |
| | | smr.normalizeSubstring(subInitialElement); |
| | | ByteString nSI2 = |
| | | smr.normalizeSubstring(f.subInitialElement); |
| | | |
| | | if (! nSI1.equals(nSI2)) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | if (subFinalElement == null) |
| | | { |
| | | if (f.subFinalElement != null) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (f.subFinalElement == null) |
| | | { |
| | | return false; |
| | | } |
| | | try |
| | | { |
| | | ByteString nSF1 = |
| | | smr.normalizeSubstring(subFinalElement); |
| | | ByteString nSF2 = |
| | | smr.normalizeSubstring(f.subFinalElement); |
| | | |
| | | if (! nSF1.equals(nSF2)) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | if (subAnyElements.size() != f.subAnyElements.size()) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | for (int i = 0; i < subAnyElements.size(); i++) |
| | | { |
| | | try |
| | | { |
| | | ByteString nSA1 = |
| | | smr.normalizeSubstring(subAnyElements.get(i)); |
| | | ByteString nSA2 = |
| | | smr.normalizeSubstring(f.subAnyElements.get(i)); |
| | | |
| | | if (! nSA1.equals(nSA2)) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | |
| | |
| | | } |
| | | else |
| | | { |
| | | MatchingRule mr = |
| | | DirectoryServer.getMatchingRule( |
| | | toLowerCase(matchingRuleID)); |
| | | if (mr == null) |
| | | MatchingRule mrule = DirectoryServer.getMatchingRule(toLowerCase(matchingRuleID)); |
| | | if (mrule == null) |
| | | { |
| | | return false; |
| | | } |
| | |
| | | { |
| | | try |
| | | { |
| | | Assertion assertion = mr.getAssertion(f.assertionValue); |
| | | return assertion.matches(mr.normalizeAttributeValue(assertionValue)).toBoolean(); |
| | | Assertion assertion = mrule.getAssertion(f.assertionValue); |
| | | return assertion.matches(mrule.normalizeAttributeValue(assertionValue)).toBoolean(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | |
| | | case EQUALITY: |
| | | return typeAndAssertionHashCode(); |
| | | case SUBSTRING: |
| | | hashCode = attributeType.hashCode(); |
| | | |
| | | SubstringMatchingRule smr = |
| | | attributeType.getSubstringMatchingRule(); |
| | | |
| | | hashCode = hashCode(hashCode, smr, subInitialElement); |
| | | |
| | | if (subAnyElements != null) |
| | | { |
| | | for (ByteString e : subAnyElements) |
| | | { |
| | | hashCode = hashCode(hashCode, smr, e); |
| | | } |
| | | } |
| | | |
| | | hashCode = hashCode(hashCode, smr, subFinalElement); |
| | | |
| | | return hashCode; |
| | | return substringHashCode(); |
| | | case GREATER_OR_EQUAL: |
| | | return typeAndAssertionHashCode(); |
| | | case LESS_OR_EQUAL: |
| | |
| | | case APPROXIMATE_MATCH: |
| | | return typeAndAssertionHashCode(); |
| | | case EXTENSIBLE_MATCH: |
| | | hashCode = 0; |
| | | |
| | | if (attributeType != null) |
| | | { |
| | | hashCode += attributeType.hashCode(); |
| | | } |
| | | |
| | | if (dnAttributes) |
| | | { |
| | | hashCode++; |
| | | } |
| | | |
| | | if (matchingRuleID != null) |
| | | { |
| | | hashCode += matchingRuleID.hashCode(); |
| | | } |
| | | |
| | | if (assertionValue != null) |
| | | { |
| | | hashCode += assertionValue.hashCode(); |
| | | } |
| | | |
| | | return hashCode; |
| | | return extensibleHashCode(); |
| | | default: |
| | | return 1; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** Returns the hash code for extensible filter. */ |
| | | private int extensibleHashCode() |
| | | { |
| | | int hashCode = 0; |
| | | |
| | | if (attributeType != null) |
| | | { |
| | | hashCode += attributeType.hashCode(); |
| | | } |
| | | |
| | | if (dnAttributes) |
| | | { |
| | | hashCode++; |
| | | } |
| | | |
| | | if (matchingRuleID != null) |
| | | { |
| | | hashCode += matchingRuleID.hashCode(); |
| | | } |
| | | |
| | | if (assertionValue != null) |
| | | { |
| | | hashCode += assertionValue.hashCode(); |
| | | } |
| | | return hashCode; |
| | | } |
| | | |
| | | |
| | | private int typeAndAssertionHashCode() |
| | | { |
| | | final int hashCode = attributeType.hashCode(); |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | private int hashCode(int hashCode, SubstringMatchingRule smr, |
| | | ByteString subElem) |
| | | /** Returns hash code to use for substring filter. */ |
| | | private int substringHashCode() |
| | | { |
| | | if (subElem != null) |
| | | int hashCode = attributeType.hashCode(); |
| | | final MatchingRule rule = attributeType.getSubstringMatchingRule(); |
| | | if (rule != null) |
| | | { |
| | | if (smr == null) |
| | | try |
| | | { |
| | | hashCode += subElem.hashCode(); |
| | | return hashCode + rule.getSubstringAssertion(subInitialElement, subAnyElements, subFinalElement).hashCode(); |
| | | } |
| | | else |
| | | catch (DecodeException e) |
| | | { |
| | | try |
| | | { |
| | | hashCode += smr.normalizeSubstring(subElem).hashCode(); |
| | | } |
| | | catch (Exception e) {} |
| | | logger.traceException(e); |
| | | } |
| | | } |
| | | |
| | | // Fallback to hash code based on elements |
| | | hashCode += subInitialElement.hashCode(); |
| | | for (ByteString e : subAnyElements) |
| | | { |
| | | hashCode += e.hashCode(); |
| | | } |
| | | hashCode += subFinalElement.hashCode(); |
| | | return hashCode; |
| | | } |
| | | |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | |
| | | SubstringMatchingRuleTest |
| | | { |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | @DataProvider(name="substringMatchData") |
| | | public Object[][] createSubstringMatchData() |
| | | { |
| | | return new Object[][] { |
| | | {"this is a value", "", new String[] {"this"}, "", true }, |
| | | {"this is a value", "", new String[] {"is"}, "", true }, |
| | | {"this is a value", "th", new String[] {"is"}, "", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "value", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "ue", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "e", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "valu", false }, |
| | | {"this is a value", "THIS", new String[] {"is"}, "", false }, |
| | | {"this is a value", "h", new String[] {"is"}, "", false }, |
| | | {"this is a value", "", new String[] {"a"}, "", true }, |
| | | {"this is a value", "", new String[] {"value"}, "", true }, |
| | | {"this is a value", "", new String[] {" "}, "", true }, |
| | | {"this is a value", "", new String[] {"this", "is", "a", "value"}, "", true }, |
| | | // The matching rule requires ordered non overlapping substrings |
| | | // Issue #730 was not valid. |
| | | {"this is a value", "", new String[] {"value", "this"}, "", false }, |
| | | {"this is a value", "", new String[] {"this", "this is"}, "", false }, |
| | | {"this is a value", "", new String[] {"his is", "a val",}, "", true }, |
| | | {"this is a value", "", new String[] {"not",}, "", false }, |
| | | {"this is a value", "", new String[] {"THIS",}, "", false }, |
| | | {"this is a value", "", new String[] {"this", "not"}, "", false }, |
| | | {"this is a value", "", new String[] {" "}, "", true }, |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | |
| | | SubstringMatchingRuleTest |
| | | { |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | @DataProvider(name="substringMatchData") |
| | | public Object[][] createSubstringMatchData() |
| | | { |
| | | return new Object[][] { |
| | | {"this is a value", "", new String[] {"this"}, "", true }, |
| | | {"this is a value", "", new String[] {"is"}, "", true }, |
| | | {"this is a value", "th", new String[] {"is"}, "", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "value", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "ue", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "e", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "valu", false }, |
| | | {"this is a value", "THIS", new String[] {"is"}, "", false }, |
| | | {"this is a value", "h", new String[] {"is"}, "", false }, |
| | | {"this is a value", "", new String[] {"a"}, "", true }, |
| | | {"this is a value", "", new String[] {"value"}, "", true }, |
| | | {"this is a value", "", new String[] {" "}, "", true }, |
| | | {"this is a value", "", new String[] {"this", "is", "a", "value"}, "", true }, |
| | | // The matching rule requires ordered non overlapping substrings |
| | | // Issue #730 was not valid. |
| | | {"this is a value", "", new String[] {"value", "this"}, "", false }, |
| | | {"this is a value", "", new String[] {"this", "this is"}, "", false }, |
| | | {"this is a value", "", new String[] {"his is", "a val",}, "", true }, |
| | | {"this is a value", "", new String[] {"not",}, "", false }, |
| | | {"this is a value", "", new String[] {"THIS",}, "", false }, |
| | | {"this is a value", "", new String[] {"this", "not"}, "", false }, |
| | | {"this is a value", "", new String[] {" "}, "", true }, |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | |
| | | SubstringMatchingRuleTest |
| | | { |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | @DataProvider(name="substringMatchData") |
| | | public Object[][] createSubstringMatchData() |
| | | { |
| | | return new Object[][] { |
| | | {"this is a value", "", new String[] {"this"}, "", true }, |
| | | {"this is a value", "", new String[] {"is"}, "", true }, |
| | | {"this is a value", "th", new String[] {"is"}, "", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "value", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "ue", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "e", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "valu", false }, |
| | | {"this is a value", "THIS", new String[] {"is"}, "", true }, |
| | | {"this is a value", "h", new String[] {"is"}, "", false }, |
| | | {"this is a value", "", new String[] {"a"}, "", true }, |
| | | {"this is a value", "", new String[] {"value"}, "", true }, |
| | | {"this is a value", "", new String[] {" "}, "", true }, |
| | | {"this is a value", "", new String[] {"this", "is", "a", "value"}, "", true }, |
| | | // The matching rule requires ordered non overlapping substrings |
| | | // Issue #730 was not valid. |
| | | {"this is a value", "", new String[] {"value", "this"}, "", false }, |
| | | {"this is a value", "", new String[] {"this", "this is"}, "", false }, |
| | | {"this is a value", "", new String[] {"his is", "a val",}, "", true }, |
| | | {"this is a value", "", new String[] {"not",}, "", false }, |
| | | {"this is a value", "", new String[] {"THIS",}, "", true }, |
| | | {"this is a value", "", new String[] {"this", "not"}, "", false }, |
| | | {"this is a value", "", new String[] {" "}, "", true }, |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | |
| | | SubstringMatchingRuleTest |
| | | { |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | @DataProvider(name="substringMatchData") |
| | | public Object[][] createSubstringMatchData() |
| | | { |
| | | return new Object[][] { |
| | | {"this is a value", "", new String[] {"this"}, "", true }, |
| | | {"this is a value", "", new String[] {"is"}, "", true }, |
| | | {"this is a value", "th", new String[] {"is"}, "", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "value", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "ue", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "e", true }, |
| | | {"this is a value", "this", new String[] {"is"}, "valu", false }, |
| | | {"this is a value", "THIS", new String[] {"is"}, "", true }, |
| | | {"this is a value", "h", new String[] {"is"}, "", false }, |
| | | {"this is a value", "", new String[] {"a"}, "", true }, |
| | | {"this is a value", "", new String[] {"value"}, "", true }, |
| | | {"this is a value", "", new String[] {" "}, "", true }, |
| | | {"this is a value", "", new String[] {"this", "is", "a", "value"}, "", true }, |
| | | // The matching rule requires ordered non overlapping substrings |
| | | // Issue #730 was not valid. |
| | | {"this is a value", "", new String[] {"value", "this"}, "", false }, |
| | | {"this is a value", "", new String[] {"this", "this is"}, "", false }, |
| | | {"this is a value", "", new String[] {"his is", "a val",}, "", true }, |
| | | {"this is a value", "", new String[] {"not",}, "", false }, |
| | | {"this is a value", "", new String[] {"THIS",}, "", true }, |
| | | {"this is a value", "", new String[] {"this", "not"}, "", false }, |
| | | {"this is a value", "", new String[] {" "}, "", true }, |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | |
| | | SubstringMatchingRuleTest |
| | | { |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | @DataProvider(name="substringMatchData") |
| | | public Object[][] createSubstringMatchData() |
| | | { |
| | | return new Object[][] { |
| | | // The matching rule requires ordered non overlapping substrings. |
| | | // Issue #730 was not valid. |
| | | {"123456789", "", new String[] {"123", "234", "567", "789"}, "", false }, |
| | | {"123456789", "", new String[] {"123", "234"}, "", false }, |
| | | {"123456789", "", new String[] {"567", "234"}, "", false }, |
| | | {"123456789", "", new String[] {"123", "456"}, "", true }, |
| | | {"123456789", "", new String[] {"123"}, "", true }, |
| | | {"123456789", "", new String[] {"456"}, "", true }, |
| | | {"123456789", "", new String[] {"789"}, "", true }, |
| | | {"123456789", "", new String[] {"123456789"}, "", true }, |
| | | {"123456789", "", new String[] {"1234567890"}, "", false }, |
| | | {"123456789", "", new String[] {"9"}, "", true }, |
| | | {"123456789", "", new String[] {"1"}, "", true }, |
| | | {"123456789", "", new String[] {"0"}, "", false }, |
| | | {"123456789", "", new String[] {" "}, "", true }, |
| | | {"123456789", "", new String[] {"0123"}, "", false }, |
| | | }; |
| | | } |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | |
| | | import java.util.List; |
| | | |
| | | import org.opends.server.api.SubstringMatchingRule; |
| | | import org.forgerock.opendj.ldap.Assertion; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.ByteSequence; |
| | | import org.testng.annotations.DataProvider; |
| | |
| | | * This class is intended to be extended by one class for each substring |
| | | * matching rules. |
| | | */ |
| | | @SuppressWarnings("javadoc") |
| | | public abstract class SubstringMatchingRuleTest extends SchemaTestCase |
| | | { |
| | | /** |
| | | * Generate data for the test of the assertion match. |
| | | */ |
| | | @DataProvider(name="substringMatchData") |
| | | public abstract Object[][] createSubstringMatchData(); |
| | | |
| | | /** |
| | | * Generate data for the test of the middle string match. |
| | | * |
| | | * @return the data for the test of the middle string match. |
| | |
| | | * Test the normalization and the initial substring match. |
| | | */ |
| | | @Test(dataProvider= "substringInitialMatchData") |
| | | public void initialMatchingRules( |
| | | String value, String initial, Boolean result) throws Exception |
| | | public void initialMatchingRules(String value, String initial, Boolean result) throws Exception |
| | | { |
| | | SubstringMatchingRule rule = getRule(); |
| | | |
| | |
| | | * Test the normalization and the final substring match. |
| | | */ |
| | | @Test(dataProvider= "substringFinalMatchData") |
| | | public void finalMatchingRules( |
| | | String value, String finalValue, Boolean result) throws Exception |
| | | public void finalMatchingRules(String value, String finalValue, Boolean result) throws Exception |
| | | { |
| | | SubstringMatchingRule rule = getRule(); |
| | | |
| | |
| | | value + " and " + finalValue); |
| | | } |
| | | } |
| | | |
| | | @Test(dataProvider= "substringMatchData") |
| | | public void testSubstringAssertion(String value, String initialSub, String[] middleSubs, String finalSub, |
| | | Boolean expectedResult) throws Exception |
| | | { |
| | | SubstringMatchingRule rule = getRule(); |
| | | ByteString normalizedValue = rule.normalizeAttributeValue(ByteString.valueOf(value)); |
| | | ArrayList<ByteSequence> anySubs = new ArrayList<ByteSequence>(middleSubs.length); |
| | | for (String sub : middleSubs) |
| | | { |
| | | anySubs.add(ByteString.valueOf(sub)); |
| | | } |
| | | Assertion assertion = rule.getSubstringAssertion( |
| | | ByteString.valueOf(initialSub), |
| | | anySubs, |
| | | ByteString.valueOf(finalSub)); |
| | | |
| | | Boolean result = assertion.matches(normalizedValue).toBoolean(); |
| | | assertEquals(result, expectedResult); |
| | | |
| | | } |
| | | } |