// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.text; /** *

Superclasses of parsers of a map represented textually as * {key1:value1,"anystringkey":value2,'anystringkey2':value3 ...}. * This parser must be extended to specify how to handle the key/value pairs.

* *

Example: To create a Double map parser:

*
 * public static final class DoubleMapParser extends MapParser<Double> {
 *     private Map<String, Double> map;
 *
 *     ...
 *
 *     @Override
 *     protected Double handleKeyValue(String key, String value) {
 *         map.put(key, Double.parseDouble(value));
 *     }
 *
 * }
 * 
* *

Map parsers are NOT multithread safe, but are cheap to construct.

* * @author bratseth */ public abstract class SimpleMapParser { private PositionedString s; /** * Parses a map on the form {key1:value1,key2:value2 ...} * * @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); } } 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); } } protected int findEndOfKey() { for (int peekI=s.position(); peekI