/** * Adds attributes with the specified bitmap to normalizer. * @param attribute Attribute to add * @param value Value of attribute * @param bitmap Bitmap as a hex number, with a '0x' prefix. */ private void parseBitmapHex(String attribute, String value, String bitmap) { PositionedString s = new PositionedString(bitmap); s.consume('0'); s.consume('x'); addAttribute(attribute, value, new BigInteger(s.substring().trim(),16)); }
private String consumeKey() { if (s.consumeOptional('"')) { String key=s.consumeTo('"'); s.consume('"'); return key; } else if (s.consumeOptional('\'')) { String key=s.consumeTo('\''); s.consume('\''); return key; } else { int keyEnd=findEndOfKey(); if (keyEnd<0) throw new IllegalArgumentException("Expected a key followed by ':' " + s.at()); return s.consumeToPosition(keyEnd); } }
/** * Sets the position of this to the next occurrence of c after the current position. * * @param c the char to move the position to * @return the substring between the current position and the new position at c * @throws IllegalArgumentException if there was no occurrence of c after the current position */ public String consumeTo(char c) { int nextC=indexOf(c); if (nextC<0) throw new IllegalArgumentException("Expected a string terminated by '" + c + "' " + at()); String value=substring(nextC); p=nextC; return value; }
/** * Adds attributes with the specified bitmap to normalizer. * @param attribute Attribute to add * @param value Value of attribute * @param bitmap Bitmap as a list of bits, e.g. '[0, 3, 45]' */ private void parseBitmapList(String attribute, String value, String bitmap) { PositionedString s = new PositionedString(bitmap); s.consume('['); BigInteger mask = BigInteger.ZERO; while (!s.peek(']')) { s.consumeSpaces(); int pos = findNextButSkipLists(new char[]{',',']'}, s.string(), s.position()); if (pos == -1) { break; } int subqueryIndex = Integer.parseUnsignedInt(s.substring(pos).trim()); if (subqueryIndex > 63 || subqueryIndex < 0) { throw new IllegalArgumentException("Subquery index must be in the range 0-63"); } mask = mask.or(BigInteger.ONE.shiftLeft(subqueryIndex)); s.setPosition(pos); s.consumeOptional(','); s.consumeSpaces(); } addAttribute(attribute, value, mask); }
/** * Parses a map on the form <code>{key1:value1,key2:value2 ...}</code> * * @param string the textual representation of the map */ public void parse(String string) { try { this.s=new PositionedString(string); s.consumeSpaces(); s.consume('{'); while ( ! s.peek('}')) { s.consumeSpaces(); String key=consumeKey(); s.consume(':'); s.consumeSpaces(); consumeValue(key); s.consumeOptional(','); s.consumeSpaces(); } s.consume('}'); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("'" + s + "' is not a legal sparse vector string",e); } }
protected void consumeValue(String key) { // find the next comma or bracket, whichever is next int endOfValue=findEndOfValue(); if (endOfValue<0) { throw new IllegalArgumentException("Expected a value followed by ',' or '}' " + s.at()); } try { handleKeyValue(key, s.substring(endOfValue)); s.setPosition(endOfValue); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Expected a legal value from position " + s.position() + " to " + endOfValue + " but was '" + s.substring(endOfValue) + "'", e); } }
/** Returns a textual description of the current position, useful for appending to error messages. */ public String at() { return at(p); }
/** * Returns the substring between the current position and <code>position</code> * and advances the current position to <code>position</code> */ public String consumeToPosition(int position) { String consumed=substring(position); p=position; return consumed; }
@Override protected void handleKeyValue(String attribute, String value) { // string() will point to the start of value. if (string().peek('[') && isMap) { // begin parsing MultiValueQueryTerm isMap = false; parseMultiValue(attribute); isMap = true; } else { handleAttribute(attribute, value); } }
/** * Parses a list of values for a given attribute. When calling this * function, string() must point to the start of the list. */ private void parseMultiValue(String attribute) { // string() will point to the start of value. string().consume('['); while (!string().peek(']')) { string().consumeSpaces(); consumeValue(attribute); string().consumeOptional(','); string().consumeSpaces(); } }
/** * Consumes the character at this position. * <br>Precondition: The character at this position is c. * <br>Postcondition: The position is increased by 1 * * @param c the expected character at this * @throws IllegalArgumentException if the character at this position is not c */ public void consume(char c) { if (s.charAt(p++)!=c) throw new IllegalArgumentException("Expected '" + c + "' " + at(p -1)); }