Package org.xmlBlaster.protocol.http.simple

Source Code of org.xmlBlaster.protocol.http.simple.PullServlet$Position

package org.xmlBlaster.protocol.http.simple;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Properties;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.xmlBlaster.client.I_Callback;
import org.xmlBlaster.client.I_XmlBlasterAccess;
import org.xmlBlaster.client.key.GetKey;
import org.xmlBlaster.client.key.PublishKey;
import org.xmlBlaster.client.key.UpdateKey;
import org.xmlBlaster.client.qos.ConnectQos;
import org.xmlBlaster.client.qos.GetQos;
import org.xmlBlaster.client.qos.PublishQos;
import org.xmlBlaster.client.qos.UpdateQos;
import org.xmlBlaster.util.Global;
import org.xmlBlaster.util.MsgUnit;
import org.xmlBlaster.util.StringPairTokenizer;
import org.xmlBlaster.util.XmlBlasterException;

//Debug: ~/apache-tomcat-5.5.15/bin/catalina.sh jpda start

/**
* This servlet supports requests from a browser, it queries the topic given by
* "gpsTopicId" configuration which needs to contain GPS coordinates (published
* for example by a PDA).
*
* <p>
* Use xmlBlaster/demo/http/gpsmap.html to display the coordinates in a map.
* </p>
*
* @author Marcel Ruff xmlBlaster@marcelruff.info 2006
*/
public class PullServlet extends HttpServlet {
  private static final long serialVersionUID = -8094289301696678030L;

  private Properties props = new Properties();

  private I_XmlBlasterAccess xmlBlasterAccess;

  private String loginName = "pullServlet";

  private String passwd = "something";

  public void init(ServletConfig conf) throws ServletException {
    super.init(conf);
    // Add the web.xml parameters to our environment settings:
    Enumeration enumer = conf.getInitParameterNames();
    while (enumer.hasMoreElements()) {
      String name = (String) enumer.nextElement();
      if (name != null && name.length() > 0)
        props.setProperty(name, conf.getInitParameter(name));
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
    doGet(req, res);
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
    String host = req.getRemoteAddr();
    String ME = "PullServlet.doGet(" + host + "): ";
    // log(ME + "Entering doGet ...");
    boolean forceLoad = req.getParameter("forceLoad") != null;
    if (forceLoad)
      log(ME + "forceLoad=" + forceLoad);
    boolean newBrowser = false;
    if (req.getSession(false) == null) {
      req.getSession(true);
      newBrowser = true;
      log(ME + "new browser arrived, charset="
          + req.getCharacterEncoding());
    }

    // set header field first
    res.setContentType("text/plain; charset=UTF-8");
    PrintWriter out = res.getWriter();

    try {
      if (isAction(ME, req, res))
        return;

      String feedback = getFeedback(req);
      if (feedbackHasChanged(req, feedback)) {
        out.print(feedback);
        log(ME + feedback);
        return;
      }

      Position pos = getCurrentPosition(req);
      if (pos == null) {
        // log(ME+"no data found ...");
        if (newBrowser || forceLoad) {
          out.print(getStartupUrl());
          log(ME + getStartupUrl());
        }
        return;
      }

      if (forceLoad || positionHasChanged(req, pos)) {
        String url = getUrl(pos);
        out.print(url);
        log(ME + "Send new url=" + url);
      }
      // log(ME+"Ignoring identical");

    } catch (XmlBlasterException e) {
      log("newBrowser=" + newBrowser + " forceLoad=" + forceLoad + ": "
          + e.toString());
      if (newBrowser || forceLoad)
        out.write(getStartupUrl());
    } finally {
      out.close();

    }
  }

  private boolean isAction(String ME, HttpServletRequest req,
      HttpServletResponse res) throws ServletException, IOException,
      XmlBlasterException {
    String actionType = (String) req.getParameter("action");
    String smsText = (String) req.getParameter("cheapSmsSend");
    if (actionType != null && "publish".equals(actionType)) {
      log(ME + "Got action = '" + actionType + "' -> '" + smsText + "'");
      I_XmlBlasterAccess xmlBlaster = getXmlBlaster(req);
      String topicId = props.getProperty("smsBroadcastTopicId",
          "vehicle.sms.broadcast");
      PublishKey pk = new PublishKey(xmlBlaster.getGlobal(), topicId,
          "text/xml", "1.0");
      PublishQos pq = new PublishQos(xmlBlaster.getGlobal());
      pq.addClientProperty("sender", req.getSession().getId()); // TODO:
                                    // nice
                                    // name
      MsgUnit msgUnit = new MsgUnit(pk, smsText.getBytes("UTF-8"), pq);
      xmlBlaster.publish(msgUnit);
      return true;
    }
    return false;
  }

  private String getFeedback(HttpServletRequest req)
      throws XmlBlasterException, UnsupportedEncodingException {
    I_XmlBlasterAccess xmlBlaster = getXmlBlaster(req);
    String topicId = props.getProperty("smsFeedbackTopicId",
        "vehicle.sms.feedback");
    GetKey gk = new GetKey(xmlBlaster.getGlobal(), topicId);
    GetQos gq = new GetQos(xmlBlaster.getGlobal());
    MsgUnit[] msgs = xmlBlaster.getCached(gk, gq);
    if (msgs.length > 0) {
      // log(ME+ msgs.length + " msgs found ...");
      byte[] content = msgs[msgs.length - 1].getContent();
      String sms = new String(content, "UTF-8");
      return sms.trim();
    }
    return null;
  }

  private Position getCurrentPosition(HttpServletRequest req)
      throws XmlBlasterException {
    I_XmlBlasterAccess xmlBlaster = getXmlBlaster(req);
    String topicId = props.getProperty("gpsTopicId", "vehicle.location");
    GetKey gk = new GetKey(xmlBlaster.getGlobal(), topicId);
    GetQos gq = new GetQos(xmlBlaster.getGlobal());
    MsgUnit[] msgs = xmlBlaster.getCached(gk, gq);
    if (msgs.length > 0) {
      // log(ME+ msgs.length + " msgs found ...");
      byte[] content = msgs[msgs.length - 1].getContent();
      return parsePosition(content);
    }
    return null;
  }

  // Only call once for each request
  private boolean feedbackHasChanged(HttpServletRequest req, String sms) {
    if (sms == null || sms.length() < 1)
      return false;
    HttpSession session = req.getSession(true);
    String lastFeedback = (String) session.getAttribute("lastFeedback");
    if (lastFeedback != null && lastFeedback.equals(sms)) {
      return false;
    }
    session.setAttribute("lastFeedback", sms);
    return true;
  }

  // Only call once for each request
  private boolean positionHasChanged(HttpServletRequest req, Position pos) {
    HttpSession session = req.getSession(true);
    Position lastPos = (Position) session.getAttribute("lastPosition");
    if (lastPos != null && lastPos.equals(pos)) {
      return false;
    }
    session.setAttribute("lastPosition", pos);
    return true;
  }

  private synchronized I_XmlBlasterAccess getXmlBlaster(HttpServletRequest req)
      throws XmlBlasterException {
    // HttpSession session = req.getSession(true);
    // I_XmlBlasterAccess xmlBlaster = (I_XmlBlasterAccess) session
    // .getAttribute("xmlBlaster");
    if (this.xmlBlasterAccess == null) {
      if (!props.containsKey("dispatch/callback/retries"))
        props.put("dispatch/callback/retries", "-1");
      String sessionName = props.getProperty("sessionName", loginName
          + "/1");
      String password = props.getProperty("password", passwd);
      Global glob = new Global(props);
      this.xmlBlasterAccess = glob.getXmlBlasterAccess();
      ConnectQos qos = new ConnectQos(glob, sessionName, password);
      this.xmlBlasterAccess.connect(qos, new I_Callback() {
        public String update(String cbSessionId, UpdateKey updateKey,
            byte[] content, UpdateQos updateQos) {
          log("PullServler.update(): Ignoring update "
              + updateKey.getOid());
          return "";
        }
      });
      this.xmlBlasterAccess.createSynchronousCache(20);
      // session.setAttribute("xmlBlaster", xmlBlaster);
    }
    return this.xmlBlasterAccess;
  }

  public String getUrl(Position pos) {
    StringBuffer url = new StringBuffer();
    url.append("http://maps.google.com/maps?q=");
    url.append(pos.latitude).append(",+").append(pos.longitude);
    url.append("+(").append(pos.label).append(")&iwloc=A&hl=en");
    // String encoded = Global.encode(url.toString(), null);
    return url.toString();
  }

  public String getStartupUrl() {
    // http://maps.google.com/maps?q=047%C2%B042'20.41%22,+009%C2%B012'06.80%22+(Gran'ma%20on%20tour)&iwloc=A&hl=en
    // "047°42'20.41\"", "009°12'06.80\""
    Position pos = new Position();
    pos.label = "Gran'ma is at home";
    pos.latitude = "047%C2%B042'20.41%22";
    pos.longitude = "009%C2%B012'06.80%22";
    return getUrl(pos);
  }

  // Expecting a PDA sending me Gran'mas position
  // with simplified NMEA:
  // >Gran'mas place,047°46'55.86",N,009°10'00.95",E,0<
  public Position parsePosition(byte[] data_) {

    String data;
    try {
      data = new String(data_, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
      throw new IllegalArgumentException(e.toString());
    }
    Position pos = new Position();
    String[] tokens = StringPairTokenizer.toArray(data, ",");
    if (tokens.length < 6)
      throw new IllegalArgumentException("Illegal data: " + data);
    pos.label = tokens[0];
    pos.latitude = tokens[1];
    pos.latitudeL = tokens[2];
    pos.longitude = tokens[3];
    pos.longitudeL = tokens[4];
    pos.heading = tokens[5];
    return pos;
  }

  class Position {
    String label = ""; // "Gran'ma on tour

    String latitude = "";

    String latitudeL = ""; // N S

    String longitude = "";

    String longitudeL = ""; // E W

    String heading = ""; // direction degree

    public String toString() {
      return "label=" + label + " latitude=" + latitude + " longitude="
          + longitude;
    }

    public boolean equals(Position other) {
      if (label.equals(other.label) && latitude.equals(other.latitude)
          && longitude.equals(other.longitude))
        return true;
      return false;
    }
  }

  public String getServletInfo() {
    return "Unprotected access to xmlBlaster";
  }

  public synchronized void destroy() {
    if (xmlBlasterAccess != null) {
      try {
        xmlBlasterAccess.disconnect(null);
      } catch (Throwable e) {
        log("Ignoring disconnect problem " + e.toString());
      } finally {
        xmlBlasterAccess = null;
      }
    }
  }

  public void log(String text) {
    // System.err.println("ERR"+text);
    // System.out.println("OUT"+text);
    super.log(text);
  }
}
TOP

Related Classes of org.xmlBlaster.protocol.http.simple.PullServlet$Position

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.