opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java
@@ -131,8 +131,8 @@ // The next character must be an equal sign. If it is not, then // that's an error. char c; if ((c = reader.read()) != '=') { final char c = reader.read(); if (c != '=') { final LocalizableMessage message = ERR_ATTR_SYNTAX_DN_NO_EQUAL .get(reader.getString(), attribute.getNameOrOID(), c); opendj-core/src/main/java/org/forgerock/opendj/ldap/Matcher.java
@@ -234,10 +234,7 @@ public MatcherImpl visitApproxMatchFilter(final Schema schema, final String attributeDescription, final ByteString assertionValue) { AttributeDescription ad; MatchingRule rule; Assertion assertion; final AttributeDescription ad; try { ad = AttributeDescription.valueOf(attributeDescription, schema); } catch (final LocalizedIllegalArgumentException e) { @@ -247,13 +244,15 @@ return UNDEFINED; } if ((rule = ad.getAttributeType().getApproximateMatchingRule()) == null) { final MatchingRule rule = ad.getAttributeType().getApproximateMatchingRule(); if (rule == null) { // TODO: I18N logger.warn(LocalizableMessage.raw("The attribute type %s does not define an approximate matching rule", attributeDescription)); return UNDEFINED; } final Assertion assertion; try { assertion = rule.getAssertion(assertionValue); } catch (final DecodeException de) { @@ -266,10 +265,7 @@ public MatcherImpl visitEqualityMatchFilter(final Schema schema, final String attributeDescription, final ByteString assertionValue) { AttributeDescription ad; MatchingRule rule; Assertion assertion; final AttributeDescription ad; try { ad = AttributeDescription.valueOf(attributeDescription, schema); } catch (final LocalizedIllegalArgumentException e) { @@ -279,13 +275,15 @@ return UNDEFINED; } if ((rule = ad.getAttributeType().getEqualityMatchingRule()) == null) { final MatchingRule rule = ad.getAttributeType().getEqualityMatchingRule(); if (rule == null) { // TODO: I18N logger.warn(LocalizableMessage.raw("The attribute type %s does not define an equality matching rule", attributeDescription)); return UNDEFINED; } final Assertion assertion; try { assertion = rule.getAssertion(assertionValue); } catch (final DecodeException de) { @@ -325,7 +323,8 @@ } if (rule == null) { if ((rule = ad.getAttributeType().getEqualityMatchingRule()) == null) { rule = ad.getAttributeType().getEqualityMatchingRule(); if (rule == null) { // TODO: I18N logger.warn(LocalizableMessage.raw( "The attribute type %s does not define an equality matching rule", @@ -372,10 +371,7 @@ public MatcherImpl visitGreaterOrEqualFilter(final Schema schema, final String attributeDescription, final ByteString assertionValue) { AttributeDescription ad; MatchingRule rule; Assertion assertion; final AttributeDescription ad; try { ad = AttributeDescription.valueOf(attributeDescription, schema); } catch (final LocalizedIllegalArgumentException e) { @@ -386,13 +382,15 @@ return UNDEFINED; } if ((rule = ad.getAttributeType().getOrderingMatchingRule()) == null) { final MatchingRule rule = ad.getAttributeType().getOrderingMatchingRule(); if (rule == null) { // TODO: I18N logger.warn(LocalizableMessage.raw("The attribute type %s does not define an ordering matching rule", attributeDescription)); return UNDEFINED; } final Assertion assertion; try { assertion = rule.getGreaterOrEqualAssertion(assertionValue); } catch (final DecodeException de) { @@ -405,10 +403,7 @@ public MatcherImpl visitLessOrEqualFilter(final Schema schema, final String attributeDescription, final ByteString assertionValue) { AttributeDescription ad; MatchingRule rule; Assertion assertion; final AttributeDescription ad; try { ad = AttributeDescription.valueOf(attributeDescription, schema); } catch (final LocalizedIllegalArgumentException e) { @@ -418,13 +413,15 @@ return UNDEFINED; } if ((rule = ad.getAttributeType().getOrderingMatchingRule()) == null) { final MatchingRule rule = ad.getAttributeType().getOrderingMatchingRule(); if (rule == null) { // TODO: I18N logger.warn(LocalizableMessage.raw("The attribute type %s does not define an ordering matching rule", attributeDescription)); return UNDEFINED; } final Assertion assertion; try { assertion = rule.getLessOrEqualAssertion(assertionValue); } catch (final DecodeException de) { @@ -470,10 +467,7 @@ public MatcherImpl visitSubstringsFilter(final Schema schema, final String attributeDescription, final ByteString initialSubstring, final List<ByteString> anySubstrings, final ByteString finalSubstring) { AttributeDescription ad; MatchingRule rule; Assertion assertion; final AttributeDescription ad; try { ad = AttributeDescription.valueOf(attributeDescription, schema); } catch (final LocalizedIllegalArgumentException e) { @@ -483,13 +477,15 @@ return UNDEFINED; } if ((rule = ad.getAttributeType().getSubstringMatchingRule()) == null) { final MatchingRule rule = ad.getAttributeType().getSubstringMatchingRule(); if (rule == null) { // TODO: I18N logger.warn(LocalizableMessage.raw("The attribute type %s does not define an substring matching rule", attributeDescription)); return UNDEFINED; } final Assertion assertion; try { assertion = rule.getSubstringAssertion(initialSubstring, anySubstrings, finalSubstring); } catch (final DecodeException de) { @@ -512,16 +508,13 @@ private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); private static final MatcherImpl FALSE = new FalseMatcherImpl(); private static final MatcherImpl TRUE = new TrueMatcherImpl(); private static final MatcherImpl UNDEFINED = new UndefinedMatcherImpl(); private static final FilterVisitor<MatcherImpl, Schema> VISITOR = new Visitor(); private static ConditionResult matches(final Attribute a, final MatchingRule rule, final Assertion assertion) { ConditionResult r = ConditionResult.FALSE; if (a != null) { for (final ByteString v : a) { opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/DoubleMetaphoneApproximateMatchingRuleImpl.java
@@ -64,8 +64,7 @@ final int last = length - 1; // Pad the value to allow for checks to go past the end of the // value. // Pad the value to allow for checks to go past the end of the value. valueString = valueString.toUpperCase() + " "; // The metaphone value that is being constructed. @@ -87,8 +86,7 @@ // Loop until we have at least four metaphone characters or have // reached the end of the string. while (metaphone.length() < 4 && pos < length) { // Check the character at the current position against various // targets. // Check the character at the current position against various targets. char posMinusFour; char posMinusThree; char posMinusTwo; @@ -122,8 +120,8 @@ break; case 'C': // Check for various Germanic sequences, which will be mapped to // 'K'. This basically includes all occurrences of "ACH" where // Check for various Germanic sequences, which will be mapped to 'K'. // This basically includes all occurrences of "ACH" where // the preceding character is not a vowel and the following // character is neither an 'E' nor an 'I' except in "BACHER" and // "MACHER". @@ -131,15 +129,15 @@ && !isVowel(posMinusTwo = valueString.charAt(pos - 2)) && hasSubstring(valueString, pos - 1, "ACH") && (posPlusTwo = valueString.charAt(pos + 2)) != 'I' && (posPlusTwo != 'E' || valueString.charAt(pos + 3) == 'R' && (posMinusTwo == 'B' || posMinusTwo == 'M'))) { && (posPlusTwo != 'E' || (valueString.charAt(pos + 3) == 'R' && (posMinusTwo == 'B' || posMinusTwo == 'M')))) { metaphone.append("K"); pos += 2; break; } // Check for a special case of "caesar", which will be maped to // 'S'. // Check for a special case of "caesar", which will be mapped to 'S'. if (pos == 0 && hasSubstring(valueString, pos + 1, "AESAR")) { metaphone.append("S"); pos += 2; @@ -147,7 +145,8 @@ } // CH can be treated in lots of different ways. if ((posPlusOne = valueString.charAt(pos + 1)) == 'H') { posPlusOne = valueString.charAt(pos + 1); if (posPlusOne == 'H') { // Check for "chia" as in "chianti" and map to 'K'. if (hasSubstring(valueString, pos + 2, "IA")) { metaphone.append("K"); @@ -226,7 +225,8 @@ // Check for a double C but not in values that start with "McC" if (posPlusOne == 'C' && !(pos == 1 && valueString.charAt(0) == 'M')) { if (((posPlusTwo = valueString.charAt(pos + 2)) == 'I' || posPlusTwo == 'E' || posPlusTwo == 'H') posPlusTwo = valueString.charAt(pos + 2); if ((posPlusTwo == 'I' || posPlusTwo == 'E' || posPlusTwo == 'H') && !(posPlusTwo == 'H' && valueString.charAt(pos + 3) == 'U')) { if ((pos == 1 && valueString.charAt(pos - 1) == 'A') || hasSubstring(valueString, pos - 1, "UCCEE") @@ -251,8 +251,8 @@ // Check for CK, CG, or CQ and map to 'K'. Check for CI, CE, and // CY and map to "S". if ((posPlusOne = valueString.charAt(pos + 1)) == 'K' || posPlusOne == 'G' || posPlusOne == 'Q') { posPlusOne = valueString.charAt(pos + 1); if (posPlusOne == 'K' || posPlusOne == 'G' || posPlusOne == 'Q') { metaphone.append("K"); pos += 2; break; @@ -311,17 +311,17 @@ case 'D': // DG will be mapped to either 'J' (in cases like edge) or 'TK' // (in cases like Edgar). if ((posPlusOne = valueString.charAt(pos + 1)) == 'G') { if ((posPlusTwo = valueString.charAt(pos + 2)) == 'I' || posPlusTwo == 'E' || posPlusTwo == 'Y') { posPlusOne = valueString.charAt(pos + 1); if (posPlusOne == 'G') { posPlusTwo = valueString.charAt(pos + 2); if (posPlusTwo == 'I' || posPlusTwo == 'E' || posPlusTwo == 'Y') { metaphone.append("J"); pos += 3; break; } else { metaphone.append("TK"); pos += 2; break; } break; } // DT and DD will be mapped to 'T'. @@ -337,8 +337,7 @@ break; case 'F': // F always maps to F. If there is a double F, then skip the // second one. // F always maps to F. If there is a double F, then skip the second one. metaphone.append("F"); pos++; if (valueString.charAt(pos) == 'F') { @@ -347,9 +346,9 @@ break; case 'G': if ((posPlusOne = valueString.charAt(pos + 1)) == 'H') { // A "GH" that is not preceded by a vowel will be mapped to // 'K'. posPlusOne = valueString.charAt(pos + 1); if (posPlusOne == 'H') { // A "GH" that is not preceded by a vowel will be mapped to 'K'. if (pos > 0 && !isVowel(valueString.charAt(pos - 1))) { metaphone.append("K"); pos += 2; @@ -385,9 +384,7 @@ && ((posMinusThree = valueString.charAt(pos - 3)) == 'C' || posMinusThree == 'G' || posMinusThree == 'L' || posMinusThree == 'R' || posMinusThree == 'T')) { // Words like laugh, McLaughlin, cough, rough are // mapped // to 'F'. // Words like laugh, McLaughlin, cough, rough are mapped to 'F'. metaphone.append("F"); } else if (pos > 0 && valueString.charAt(pos - 1) != 'I') { metaphone.append("K"); @@ -423,26 +420,24 @@ break; } // Forms of GY, GE, and GI at the beginning of a word will map // to 'K'. // Forms of GY, GE, and GI at the beginning of a word will map to 'K'. if (pos == 0 && (posPlusOne == 'Y' || (substring = valueString.substring(pos + 1, pos + 3)) .equals("ES") || substring.equals("EP") || (substring = valueString.substring(pos + 1, pos + 3)).equals("ES") || substring.equals("EP") || substring.equals("EB") || substring.equals("EL") || substring.equals("EY") || substring.equals("IB") || substring.equals("IL") || substring.equals("IN") || substring.equals("IE") || substring.equals("EI") || substring .equals("ER"))) { || substring.equals("IE") || substring.equals("EI") || substring.equals("ER"))) { metaphone.append("K"); pos += 2; break; } // Some occurrences of GER and GY in a word will be mapped to // 'K'. // Some occurrences of GER and GY in a word will be mapped to 'K'. posPlusTwo = valueString.charAt(pos + 2); if ((posPlusOne == 'E' && posPlusTwo == 'R' || posPlusOne == 'Y') if (((posPlusOne == 'E' && posPlusTwo == 'R') || posPlusOne == 'Y') && (posMinusOne = valueString.charAt(pos - 1)) != 'E' && posMinusOne != 'I' && !hasSubstring(valueString, 0, "DANGER") && !hasSubstring(valueString, 0, "RANGER") @@ -484,11 +479,10 @@ // The letter 'H' will only be processed if it is immediately // followed by a vowel and is either the start of the word or // preceded by a vowel. if (isVowel(valueString.charAt(pos + 1))) { if (pos == 0 || isVowel(valueString.charAt(pos - 1))) { metaphone.append("H"); pos++; } if (isVowel(valueString.charAt(pos + 1)) && (pos == 0 || isVowel(valueString.charAt(pos - 1)))) { metaphone.append("H"); pos++; } pos++; @@ -553,10 +547,9 @@ if (valueString.charAt(pos + 1) == 'M') { pos++; } else if (hasSubstring(valueString, pos - 1, "UMB")) { if (pos + 1 == last || hasSubstring(valueString, pos + 2, "ER")) { pos++; } } else if (hasSubstring(valueString, pos - 1, "UMB") && (pos + 1 == last || hasSubstring(valueString, pos + 2, "ER"))) { pos++; } pos++; @@ -575,7 +568,8 @@ case 'P': // PH will be mapped to 'F'. if ((posPlusOne = valueString.charAt(pos + 1)) == 'H') { posPlusOne = valueString.charAt(pos + 1); if (posPlusOne == 'H') { metaphone.append("F"); pos += 2; break; @@ -613,8 +607,7 @@ break; } // All other cases will be mapped to 'R', with RR treated like // R. // All other cases will be mapped to 'R', with RR treated like R. metaphone.append("R"); if (valueString.charAt(pos + 1) == 'R') { @@ -640,7 +633,8 @@ } // SH is generally mapped to 'X', but not in Germanic cases. if ((posPlusOne = valueString.charAt(pos + 1)) == 'H') { posPlusOne = valueString.charAt(pos + 1); if (posPlusOne == 'H') { if (hasSubstring(valueString, pos + 1, "HEIM") || hasSubstring(valueString, pos + 1, "HOEK") || hasSubstring(valueString, pos + 1, "HOLM") @@ -669,8 +663,7 @@ break; } // Various combinations at the beginning of words will be mapped // to 'S'. // Various combinations at the beginning of words will be mapped to 'S'. if (pos == 0 && (posPlusOne == 'M' || posPlusOne == 'N' || posPlusOne == 'L' || posPlusOne == 'W')) { metaphone.append("S"); @@ -680,7 +673,8 @@ // SC should be mapped to either SK, X, or S. if (posPlusOne == 'C') { if ((posPlusTwo = valueString.charAt(pos + 2)) == 'H') { posPlusTwo = valueString.charAt(pos + 2); if (posPlusTwo == 'H') { if (hasSubstring(valueString, pos + 3, "OO") || hasSubstring(valueString, pos + 3, "UY") || hasSubstring(valueString, pos + 3, "ED") @@ -730,8 +724,9 @@ // TH or TTH will be mapped to either T (for Germanic cases) or // 0 (zero) for the rest. if ((posPlusOne = valueString.charAt(pos + 1)) == 'H' || posPlusOne == 'T' && valueString.charAt(pos + 2) == 'H') { posPlusOne = valueString.charAt(pos + 1); if (posPlusOne == 'H' || (posPlusOne == 'T' && valueString.charAt(pos + 2) == 'H')) { if (isGermanic(valueString) || hasSubstring(valueString, pos + 2, "OM") || hasSubstring(valueString, pos + 2, "AM")) { metaphone.append("T"); @@ -743,8 +738,7 @@ break; } // All other cases will map to T, with TT and TD being treated // like T. // All other cases will map to T, with TT and TD being treated like T. metaphone.append("T"); if (posPlusOne == 'T' || posPlusOne == 'D') { @@ -767,20 +761,18 @@ case 'W': // WR should always map to R. if ((posPlusOne = valueString.charAt(pos + 1)) == 'R') { posPlusOne = valueString.charAt(pos + 1); if (posPlusOne == 'R') { metaphone.append("R"); pos += 2; break; } // W[AEIOUYH] at the beginning of the word should be mapped to // A. // W[AEIOUYH] at the beginning of the word should be mapped to A. if (pos == 0 && (isVowel(posPlusOne) || posPlusOne == 'H')) { metaphone.append("A"); // FIXME -- This isn't in the algorithm as written. Should // it // be? // FIXME -- This isn't in the algorithm as written. Should it be? pos += 2; break; } @@ -806,7 +798,8 @@ metaphone.append("KS"); } if ((posPlusOne = valueString.charAt(pos + 1)) == 'C' || posPlusOne == 'X') { posPlusOne = valueString.charAt(pos + 1); if (posPlusOne == 'C' || posPlusOne == 'X') { pos++; } @@ -815,7 +808,8 @@ case 'Z': // Chinese usages like zhao will map to J. if ((posPlusOne = valueString.charAt(pos + 1)) == 'H') { posPlusOne = valueString.charAt(pos + 1); if (posPlusOne == 'H') { metaphone.append("J"); pos += 2; break; opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
@@ -2373,8 +2373,8 @@ numericOID2AttributeTypes.put(attribute.getOID(), attribute); for (final String name : attribute.getNames()) { final String lowerName = StaticUtils.toLowerCase(name); List<AttributeType> attrs; if ((attrs = name2AttributeTypes.get(lowerName)) == null) { List<AttributeType> attrs = name2AttributeTypes.get(lowerName); if (attrs == null) { name2AttributeTypes.put(lowerName, Collections.singletonList(attribute)); } else if (attrs.size() == 1) { attrs = new ArrayList<AttributeType>(attrs); @@ -2402,8 +2402,8 @@ numericOID2ContentRules.put(rule.getStructuralClassOID(), rule); for (final String name : rule.getNames()) { final String lowerName = StaticUtils.toLowerCase(name); List<DITContentRule> rules; if ((rules = name2ContentRules.get(lowerName)) == null) { List<DITContentRule> rules = name2ContentRules.get(lowerName); if (rules == null) { name2ContentRules.put(lowerName, Collections.singletonList(rule)); } else if (rules.size() == 1) { rules = new ArrayList<DITContentRule>(rules); @@ -2431,8 +2431,8 @@ id2StructureRules.put(rule.getRuleID(), rule); for (final String name : rule.getNames()) { final String lowerName = StaticUtils.toLowerCase(name); List<DITStructureRule> rules; if ((rules = name2StructureRules.get(lowerName)) == null) { List<DITStructureRule> rules = name2StructureRules.get(lowerName); if (rules == null) { name2StructureRules.put(lowerName, Collections.singletonList(rule)); } else if (rules.size() == 1) { rules = new ArrayList<DITStructureRule>(rules); @@ -2460,8 +2460,8 @@ numericOID2MatchingRuleUses.put(use.getMatchingRuleOID(), use); for (final String name : use.getNames()) { final String lowerName = StaticUtils.toLowerCase(name); List<MatchingRuleUse> uses; if ((uses = name2MatchingRuleUses.get(lowerName)) == null) { List<MatchingRuleUse> uses = name2MatchingRuleUses.get(lowerName); if (uses == null) { name2MatchingRuleUses.put(lowerName, Collections.singletonList(use)); } else if (uses.size() == 1) { uses = new ArrayList<MatchingRuleUse>(uses); @@ -2491,8 +2491,8 @@ numericOID2MatchingRules.put(rule.getOID(), rule); for (final String name : rule.getNames()) { final String lowerName = StaticUtils.toLowerCase(name); List<MatchingRule> rules; if ((rules = name2MatchingRules.get(lowerName)) == null) { List<MatchingRule> rules = name2MatchingRules.get(lowerName); if (rules == null) { name2MatchingRules.put(lowerName, Collections.singletonList(rule)); } else if (rules.size() == 1) { rules = new ArrayList<MatchingRule>(rules); @@ -2521,8 +2521,8 @@ numericOID2NameForms.put(form.getOID(), form); for (final String name : form.getNames()) { final String lowerName = StaticUtils.toLowerCase(name); List<NameForm> forms; if ((forms = name2NameForms.get(lowerName)) == null) { List<NameForm> forms = name2NameForms.get(lowerName); if (forms == null) { name2NameForms.put(lowerName, Collections.singletonList(form)); } else if (forms.size() == 1) { forms = new ArrayList<NameForm>(forms); @@ -2551,8 +2551,8 @@ numericOID2ObjectClasses.put(oc.getOID(), oc); for (final String name : oc.getNames()) { final String lowerName = StaticUtils.toLowerCase(name); List<ObjectClass> classes; if ((classes = name2ObjectClasses.get(lowerName)) == null) { List<ObjectClass> classes = name2ObjectClasses.get(lowerName); if (classes == null) { name2ObjectClasses.put(lowerName, Collections.singletonList(oc)); } else if (classes.size() == 1) { classes = new ArrayList<ObjectClass>(classes); @@ -2861,9 +2861,9 @@ form.validate(schema, warnings); // build the objectClass2NameForms map List<NameForm> forms; final String ocOID = form.getStructuralClass().getOID(); if ((forms = objectClass2NameForms.get(ocOID)) == null) { List<NameForm> forms = objectClass2NameForms.get(ocOID); if (forms == null) { objectClass2NameForms.put(ocOID, Collections.singletonList(form)); } else if (forms.size() == 1) { forms = new ArrayList<NameForm>(forms); @@ -2902,9 +2902,9 @@ for (final DITStructureRule rule : id2StructureRules.values()) { // build the nameForm2StructureRules map List<DITStructureRule> rules; final String ocOID = rule.getNameForm().getOID(); if ((rules = nameForm2StructureRules.get(ocOID)) == null) { List<DITStructureRule> rules = nameForm2StructureRules.get(ocOID); if (rules == null) { nameForm2StructureRules.put(ocOID, Collections.singletonList(rule)); } else if (rules.size() == 1) { rules = new ArrayList<DITStructureRule>(rules); opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java
@@ -372,7 +372,8 @@ final String oid = reader.read(length); reader.mark(); if ((c = reader.read()) == '{') { c = reader.read(); if (c == '{') { reader.mark(); // The only thing we'll allow here will be numeric digits and // the closing curly brace.