package com.parkerriver;

import java.net.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.xml.parsers.*;
import org.apache.log4j.*;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.*;

public class ZipServlet2 extends HttpServlet {
   private Logger log = null;
   private String zipCode = null;

   public String getZipCode() {
      return zipCode;
   }

   public void setZipCode(String zipCode) {
      this.zipCode = zipCode;
   }

   private static String wsUrl=
      "http://www.webservicex.net/uszip.asmx/GetInfoByState?USState=";

   public void init() throws ServletException {
      log = Logger.getLogger(ZipServlet2.class);
   }

   protected void doGet(HttpServletRequest httpServletRequest,
         HttpServletResponse httpServletResponse) throws
         ServletException, IOException {
      String stte = httpServletRequest.getParameter("state");
      String _city = httpServletRequest.getParameter("city");
      String resp = null;
      if(stte != null && _city != null){
         URL usps = new URL(wsUrl+stte);
         HttpURLConnection usp = (HttpURLConnection) usps.
            openConnection();
         usp.setRequestMethod("GET");
         usp.setDoInput(true);
         usp.connect();

         BufferedReader in = new BufferedReader(
            new InputStreamReader(
               usp.getInputStream()));
         StringBuffer buf = new StringBuffer("");
         String inputLine;
         while ((inputLine = in.readLine()) != null) {
            buf.append(inputLine);   }
         in.close();
         resp = buf.toString();
         try {
            getZipSax(resp,_city);
            resp="<zip>"+this.getZipCode()+"</zip>";
         } catch (ParserConfigurationException e) {
            e.printStackTrace();
         } 
      } else {
         resp="<error />";
      }
      httpServletResponse.setContentType("text/xml; charset=iso-8859-2");
      // Poinformowanie agenta lub przegldarki uytkownika,
      // e odpowied nie powinna by buforowana.
      httpServletResponse.setHeader("Cache-Control", "no-cache");
      httpServletResponse.getWriter().write(resp);
   }

   protected void doPost(HttpServletRequest httpServletRequest,
         HttpServletResponse httpServletResponse) throws 
         ServletException, IOException {
      doGet(httpServletRequest, httpServletResponse);
   }
/* Przetworzenie pliku XML kodw pocztowych za pomoc wasnej klasy DefaultHandler. 
ContentHandler otrzymuje nazw miasta podanego przez uytkownika. */
   private void getZipSax(String zipXML,String _city) 
         throws ParserConfigurationException, IOException {
      try {
         SAXParser parser =  SAXParserFactory.
         newInstance().newSAXParser();
         parser.parse(new InputSource(new StringReader(zipXML)),
            new MyHandler(_city));
      } catch (SAXException sxe) {
         log.info("Przechwycono SAXException: "+sxe.getMessage());
      }

   }
   /* SAX ContentHandler przetwarzajcy plik XML; gdy odnajdzie w pliku XML 
   poprawny kod pocztowy, wtedy ustawia waciwo zipCode nadrzdnej klasy,
   a nastpnie zgasza SAXException w celu zatrzymania przetwarzania. */
   class MyHandler extends DefaultHandler{
      private String city;
      private boolean foundCityFlag,foundCityVal,foundZipFlag;
      public MyHandler() {
         super();
      }
      public MyHandler(String _city) {
         this();
         this.city=_city;
      }
      public void startElement(String string, String string1,
         String string2,
         Attributes attributes) throws SAXException {
         if(string2.equalsIgnoreCase("city")){
            foundCityFlag=true;
         }
         if(foundCityVal){
            if(string2.equalsIgnoreCase("zip")){
               foundZipFlag=true;
            }
         }
      }

      public void characters(char[] chars, int i,
      int i1) throws SAXException {

         if(foundCityFlag){
            if(new String(chars,i,i1).equalsIgnoreCase(city)){
               foundCityVal=true;
            } else {
               foundCityFlag=false;
            }
         }
         if(foundZipFlag){
            setZipCode(new String(chars,i,i1));
            throw new SAXException("Kod pocztowy zosta znaleziony.");
         }
      }

   }
}
