Package org.neo4j.smack.routing

Source Code of org.neo4j.smack.routing.ResettableQueryStringDecoder

package org.neo4j.smack.routing;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.neo4j.smack.pipeline.http.HttpTokens;

// Modified verion of Nettys QueryStringDecoder,
// lets you reuse the same decoder.
// Can probably be optimized further..
public class ResettableQueryStringDecoder {

        private Charset charset;
        private String uri;
        private String path;
        private Map<String, List<String>> params;

        /**
         * Returns the decoded path string of the URI.
         */
        public String getPath() {
            if (path == null) {
                int pathEndPos = uri.indexOf('?');
                if (pathEndPos < 0) {
                    path = uri;
                }
                else {
                    return path = uri.substring(0, pathEndPos);
                }
            }
            return path;
        }

        /**
         * Returns the decoded key-value parameter pairs of the URI.
         */
        public Map<String, List<String>> getParameters() {
            if (params == null) {
                int pathLength = getPath().length();
                if (uri.length() == pathLength) {
                    return Collections.emptyMap();
                }
                params = decodeParams(uri.substring(pathLength + 1));
            }
            return params;
        }
       
        public void resetWith(String uri) {
            reset(uri, HttpTokens.DEFAULT_CHARSET);
        }

        /**
         * Creates a new decoder that decodes the specified URI encoded in the
         * specified charset.
         */
        public void reset(String uri, Charset charset) {
            if (uri == null) {
                throw new NullPointerException("uri");
            }
            if (charset == null) {
                throw new NullPointerException("charset");
            }

            this.uri = uri;
            this.charset = charset;
            this.params = null;
            this.path = null;
        }

        private Map<String, List<String>> decodeParams(String s) {
            Map<String, List<String>> params = new LinkedHashMap<String, List<String>>();
            String name = null;
            int pos = 0; // Beginning of the unprocessed region
            int i;       // End of the unprocessed region
            char c = 0// Current character
            for (i = 0; i < s.length(); i++) {
                c = s.charAt(i);
                if (c == '=' && name == null) {
                    if (pos != i) {
                        name = decodeComponent(s.substring(pos, i), charset);
                    }
                    pos = i + 1;
                } else if (c == '&') {
                    if (name == null && pos != i) {
                        // We haven't seen an `=' so far but moved forward.
                        // Must be a param of the form '&a&' so add it with
                        // an empty value.
                        addParam(params, decodeComponent(s.substring(pos, i), charset), "");
                    } else if (name != null) {
                        addParam(params, name, decodeComponent(s.substring(pos, i), charset));
                        name = null;
                    }
                    pos = i + 1;
                }
            }

            if (pos != i) {  // Are there characters we haven't dealt with?
                if (name == null) {     // Yes and we haven't seen any `='.
                    addParam(params, decodeComponent(s.substring(pos, i), charset), "");
                } else {                // Yes and this must be the last value.
                    addParam(params, name, decodeComponent(s.substring(pos, i), charset));
                }
            } else if (name != null) {  // Have we seen a name without value?
                addParam(params, name, "");
            }

            return params;
        }

        private String decodeComponent(String s, Charset charset) {
            if (s == null) {
                return "";
            }

            try {
                return URLDecoder.decode(s, charset.name());
            } catch (UnsupportedEncodingException e) {
                throw new UnsupportedCharsetException(charset.name());
            }
        }

        private void addParam(Map<String, List<String>> params, String name, String value) {
            List<String> values = params.get(name);
            if (values == null) {
                values = new ArrayList<String>(1)// Often there's only 1 value.
                params.put(name, values);
            }
            values.add(value);
        }
}
TOP

Related Classes of org.neo4j.smack.routing.ResettableQueryStringDecoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.