import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.BufferedReader;
import java.util.List;
import java.util.ArrayList;
import java.net.URLDecoder;
import java.io.UnsupportedEncodingException;

public abstract class QueryDecodeServlet extends HttpServlet {

    public static class Pair {
        public String name;
        public String value;
        public Pair( String name, String value ) {
            this.name = name;
            this.value = value;
        }
    }

    protected abstract void processQuery(
        List<Pair> list,
        HttpServletRequest request,
        HttpServletResponse response )
        throws ServletException, IOException;

    private List<Pair> decodeQuery( String query ) {
        ArrayList<Pair> list = new ArrayList<Pair>();

        if ( query == null ) return list;

        String[] pairs = query.split("\\&");
        for ( int i=0; i < pairs.length; i++) {
            String[] fields = pairs[i].split("=");
            try {
                String n =
                    URLDecoder.decode(fields[0], "ISO-8859-1");
                String v =
                    URLDecoder.decode(fields[1], "ISO-8859-1");
                list.add( new Pair(n, v) );
            }
            catch( UnsupportedEncodingException ex ) {
                // ignore, is this a good idea
            }
        }
        return list;
    }

    protected void doGet(
        HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
        List<Pair> list = decodeQuery(request.getQueryString());
        processQuery( list, request, response );
    }

    protected void doPost(
        HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
        BufferedReader rd = request.getReader();
        StringBuilder sb = new StringBuilder();
        int ch;
        while ( (ch=rd.read()) != -1 ) {
            sb.append( (char)ch);
        }
        List<Pair> list = decodeQuery( sb.toString() );
        processQuery( list, request, response );
    }
}
