| | |
| | | |
| | | |
| | | import static org.opends.server.schema.SchemaConstants.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | import static org.opends.server.schema.StringPrepProfile.*; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | |
| | | public ByteString normalizeValue(ByteSequence value) |
| | | throws DirectoryException |
| | | { |
| | | int valueLength = value.length(); |
| | | |
| | | // Find the first non-space character. |
| | | int startPos = 0; |
| | | while ((startPos < valueLength) && (value.byteAt(startPos) == ' ')) |
| | | { |
| | | startPos++; |
| | | } |
| | | |
| | | if (startPos == valueLength) |
| | | { |
| | | // This should only happen if the value is composed entirely of spaces. |
| | | // In that case, the normalized value is a single space. |
| | | return ServerConstants.SINGLE_SPACE_VALUE; |
| | | } |
| | | |
| | | |
| | | // Find the last non-space character; |
| | | int endPos = (valueLength-1); |
| | | while ((endPos > startPos) && (value.byteAt(endPos) == ' ')) |
| | | { |
| | | endPos--; |
| | | } |
| | | |
| | | |
| | | // Assume that the value contains only ASCII characters and iterate through |
| | | // it a character at a time, converting uppercase letters to lowercase. If |
| | | // we find a non-ASCII character, then fall back on a more correct method. |
| | | StringBuilder buffer = new StringBuilder(endPos-startPos+1); |
| | | boolean lastWasSpace = false; |
| | | for (int i=startPos; i <= endPos; i++) |
| | | { |
| | | byte b = value.byteAt(i); |
| | | if ((b & 0x7F) != b) |
| | | { |
| | | return normalizeNonASCII(value.subSequence(startPos, endPos + 1)); |
| | | } |
| | | |
| | | switch (b) |
| | | { |
| | | case ' ': |
| | | if (! lastWasSpace) |
| | | { |
| | | buffer.append(' '); |
| | | lastWasSpace = true; |
| | | } |
| | | break; |
| | | case 'A': |
| | | buffer.append('a'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'B': |
| | | buffer.append('b'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'C': |
| | | buffer.append('c'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'D': |
| | | buffer.append('d'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'E': |
| | | buffer.append('e'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'F': |
| | | buffer.append('f'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'G': |
| | | buffer.append('g'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'H': |
| | | buffer.append('h'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'I': |
| | | buffer.append('i'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'J': |
| | | buffer.append('j'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'K': |
| | | buffer.append('k'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'L': |
| | | buffer.append('l'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'M': |
| | | buffer.append('m'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'N': |
| | | buffer.append('n'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'O': |
| | | buffer.append('o'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'P': |
| | | buffer.append('p'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'Q': |
| | | buffer.append('q'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'R': |
| | | buffer.append('r'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'S': |
| | | buffer.append('s'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'T': |
| | | buffer.append('t'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'U': |
| | | buffer.append('u'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'V': |
| | | buffer.append('v'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'W': |
| | | buffer.append('w'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'X': |
| | | buffer.append('x'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'Y': |
| | | buffer.append('y'); |
| | | lastWasSpace = false; |
| | | break; |
| | | case 'Z': |
| | | buffer.append('z'); |
| | | lastWasSpace = false; |
| | | break; |
| | | default: |
| | | buffer.append((char) b); |
| | | lastWasSpace = false; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | |
| | | return ByteString.valueOf(buffer.toString()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Normalizes a value that contains a non-ASCII string. |
| | | * |
| | | * @param value The non-ASCII value to normalize. |
| | | * |
| | | * @return The normalized form of the provided value. |
| | | */ |
| | | private ByteString normalizeNonASCII(ByteSequence value) |
| | | { |
| | | StringBuilder buffer = new StringBuilder(); |
| | | toLowerCase(value.toString(), buffer); |
| | | prepareUnicode(buffer, value, TRIM, CASE_FOLD); |
| | | |
| | | int bufferLength = buffer.length(); |
| | | if (bufferLength == 0) |