001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.geoserver.ows;
006:
007: import org.geoserver.ows.util.KvpUtils;
008: import java.util.ArrayList;
009: import java.util.List;
010:
011: /**
012: * A kvp parser which parses a value consisting of tokens in a nested list.
013: * <p>
014: * A value in nested form is a number of lists of tokens, seperated by an outer
015: * delimeter. The tokens in each list are serarated by an inner delimiter
016: * The default outer delimiter is are parentheses ( '()' ) , the default inner
017: * delimter is a comma ( ',' ). Example:
018: * <pre>
019: * <code>
020: * key=(token11,token12,...,token1N)(token21,token22,...,token2N)(...)(tokenM1,tokenM2,...,tokenMN)
021: *
022: * where N = number of tokens in each set, and M = number of sets.
023: * </code>
024: * </pre>
025: * </p>
026: * <p>
027: * Upon processing of each token, the token is parsed into an instance of
028: * {@link #getBinding()}. Subclasses should override the method
029: * {@link #parseToken(String)}.
030: * </p>
031: * <p>
032: * By default, the {@link #parse(String)} method returns a list of lists. Each
033: * of which contains instances of {@link #getBinding()}. The {@link #parseTokenSet(List)}
034: * method may be overidden to return a differnt type of object.
035: * </p>
036: * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
037: *
038: * TODO: add a method to convert return value as to not force returning a list
039: */
040: public class NestedKvpParser extends KvpParser {
041: /**
042: * Constructs the nested kvp parser specifying the key and class binding.
043: *
044: * @param key The key to bind to.
045: * @param binding The class of each token in the value.
046: */
047: public NestedKvpParser(String key, Class binding) {
048: super (key, binding);
049: }
050:
051: /**
052: * Tokenizes the value and delegates to {@link #parseToken(String)} to
053: * parse each token.
054: */
055: public Object parse(String value) throws Exception {
056: List tokenSets = KvpUtils.readNested(value);
057:
058: for (int i = 0; i < tokenSets.size(); i++) {
059: List tokens = (List) tokenSets.get(i);
060: List parsed = new ArrayList(tokens.size());
061:
062: for (int j = 0; j < tokens.size(); j++) {
063: String token = (String) tokens.get(j);
064: parsed.add(parseToken(token));
065: }
066:
067: tokenSets.set(i, parseTokenSet(parsed));
068: }
069:
070: return parse(tokenSets);
071: }
072:
073: /**
074: * Parses the token into an instance of {@link #getBinding()}.
075: * <p>
076: * Subclasses should override this method, the default implementation
077: * just returns token passed in.
078: * </p>
079: * @param token Part of the value being parsed.
080: *
081: * @return The token parsed into an object.
082: *
083: */
084: protected Object parseToken(String token) throws Exception {
085: return token;
086: }
087:
088: /**
089: * Parses the set of tokens into a final represetnation.
090: * <p>
091: * Subclasses may choose to override this method. The default implementation
092: * just return the list passed in.
093: * </p>
094: * @param values The parsed tokens, each value is an instance of {@link #getBinding()}.
095: *
096: * @return The final object.
097: */
098: protected Object parseTokenSet(List tokenSet) throws Exception {
099: return tokenSet;
100: }
101:
102: /**
103: * Parses the set of token sets into a final representation.
104: * <p>
105: * Subclasses may choose to override this method. The default implementation
106: * just return the list passed in.
107: * </p>
108: * @param values The parsed token sets, each value is an instance of the
109: * class returned from {@link #parseTokenSet(List)}.
110: *
111: * @return The final object.
112: */
113: protected Object parse(List values) throws Exception {
114: return values;
115: }
116: }
|