package dk.thoerup.traininfoservice; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import dk.thoerup.traininfoservice.DBConnection; /** * Servlet implementation class LocateStations */ public class LocateStations extends HttpServlet { private static final long serialVersionUID = 1L; Logger logger = Logger.getLogger( LocateStations.class.toString() ); /** * @see HttpServlet#HttpServlet() */ public LocateStations() { super(); // TODO Auto-generated constructor stub } public enum Requested { BY_NAME, BY_LOCATION, NONE } protected String getStations(Connection conn, double latitude, double longitude, String name, Requested method) throws SQLException { String SQL = ""; PreparedStatement stmt = null; ResultSet res = null; StringBuffer buff = new StringBuffer(); buff.append("\n"); buff.append("\n"); try { switch (method) { case BY_LOCATION: //inner select is workaround from not being able to use a calculated column directly in where clause SQL = "SELECT * FROM ( "+ " SELECT id,name,latitude,longitude,stationcode_fjrn,stationcode_stog, " + " earth_distance( ll_to_earth(latitude,longitude), ll_to_earth(?,?))::int AS calcdist " + " FROM trainstations " + " WHERE enabled = true AND latitude IS NOT NULL AND longitude IS NOT NULL " + " ) AS trainstations2 " + "ORDER BY calcdist ASC " + "LIMIT 4 "; stmt = conn.prepareStatement(SQL); stmt.setDouble(1, latitude); stmt.setDouble(2, longitude); break; case BY_NAME: SQL = "SELECT id,name,latitude,longitude,stationcode_fjrn,stationcode_stog,0.0 " + "FROM trainstations " + "WHERE name ILIKE ? AND latitude IS NOT NULL AND longitude IS NOT NULL " + "ORDER BY name "; stmt = conn.prepareStatement(SQL); stmt.setString(1, name + "%"); break; default: // This should not be possible logger.severe("getStations(): default switch case"); } res = stmt.executeQuery(); while (res.next()) { buff.append("\n"); buff.append("").append( res.getInt(1) ).append("\n"); buff.append("").append( res.getString(2) ) .append("\n"); buff.append("").append( res.getDouble(3) ) .append("\n"); buff.append("").append( res.getDouble(4) ) .append("\n"); res.getString(5); buff.append("").append( !res.wasNull() ) .append("\n"); res.getString(6); buff.append("").append( !res.wasNull() ) .append("\n"); buff.append("").append( res.getInt(7) ) .append("\n"); buff.append("\n"); } } finally { if (res != null && !res.isClosed()) res.close(); if (stmt != null && !stmt.isClosed()) stmt.close(); } buff.append("\n"); return buff.toString(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { double longitude = 0.0; double latitude = 0.0; String name = ""; Requested method = Requested.NONE; if (request.getParameter("latitude") != null && request.getParameter("latitude") != null) { latitude = Double.parseDouble( request.getParameter("latitude") ); longitude = Double.parseDouble( request.getParameter("longitude") ); method = Requested.BY_LOCATION; } if (request.getParameter("name") != null) { name = request.getParameter("name"); method = Requested.BY_NAME; } if (method != Requested.NONE) { Connection conn = null; try { conn = DBConnection.getConnection(); String xml = getStations(conn, latitude, longitude, name, method); response.setContentType("text/xml"); response.getWriter().print(xml); conn.close(); conn = null; } catch (Exception e) { logger.log(Level.SEVERE, "Exception while finding stations", e); response.sendError(500); } finally { try { if (conn != null) conn.close(); } catch (Throwable t) {} } } else { response.sendError(400, "not enough parameters"); } } }