/* * Copyright (C) 1999-2008 Jive Software. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.openfire.fastpath.providers; import org.jivesoftware.xmpp.workgroup.AgentNotFoundException; import org.jivesoftware.xmpp.workgroup.AgentSession; import org.jivesoftware.xmpp.workgroup.Workgroup; import org.jivesoftware.xmpp.workgroup.WorkgroupProvider; import org.dom4j.Element; import org.xmpp.packet.IQ; import org.xmpp.packet.JID; import org.xmpp.packet.PacketError; import java.util.*; public class SiteTracker implements WorkgroupProvider { private Map<String, SiteUser> siteUsers = new HashMap<String, SiteUser>(); public boolean handleGet(IQ packet) { Element iq = packet.getChildElement(); String name = iq.getName(); return "site-user-history".equals(name); } /** * Check to see if the packet is a tracker packet. * * @param packet the packet to check. * @return true if we should handle this packet. */ public boolean handleSet(IQ packet) { Element iq = packet.getChildElement(); String name = iq.getName(); if ("site-user".equals(name)) { return true; } else if ("site-invite".equals(name)) { return true; } return false; } public void executeGet(IQ packet, Workgroup workgroup) { Element iq = packet.getChildElement(); String name = iq.getName(); if ("site-user-history".equals(name)) { handleUserHistoryRequest(packet, workgroup); } } private void handleUserHistoryRequest(IQ packet, Workgroup workgroup) { IQ reply; Element iq = packet.getChildElement(); try { AgentSession agentSession = workgroup.getAgentManager().getAgentSession(packet.getFrom()); if (agentSession == null) { reply = IQ.createResultIQ(packet); reply.setChildElement(packet.getChildElement().createCopy()); reply.setError(new PacketError(PacketError.Condition.not_authorized)); workgroup.send(reply); return; } } catch (AgentNotFoundException e) { reply = IQ.createResultIQ(packet); reply.setChildElement(packet.getChildElement().createCopy()); reply.setError(new PacketError(PacketError.Condition.not_authorized)); workgroup.send(reply); return; } // Define default values String sessionID = iq.attribute("sessionID").getText(); reply = IQ.createResultIQ(packet); Element views = reply.setChildElement("site-user-history", "http://jivesoftware.com/protocol/workgroup"); views.addAttribute("sessionID", sessionID); SiteUser siteUser = siteUsers.get(sessionID); if (siteUser != null) { for (PageView view : siteUser.getViews()) { Element pageView = views.addElement("page-view"); pageView.addElement("title").setText(view.getTitle()); pageView.addElement("url").setText(view.getUrl()); pageView.addElement("time").setText(Long.toString(view.getTimeViewed())); } workgroup.send(reply); } } public void executeSet(IQ packet, Workgroup workgroup) { Element iq = packet.getChildElement(); String name = iq.getName(); if ("site-user".equals(name)) { handleSiteUser(packet, workgroup); } else if ("site-invite".equals(name)) { handleInvitation(packet, workgroup); } } private void handleSiteUser(IQ packet, Workgroup workgroup) { IQ reply; Element iq = packet.getChildElement(); // Define default values IQ update = new IQ(); Element elem = update.setChildElement("site-user", "http://jivesoftware.com/protocol/workgroup"); String sessionID = iq.attribute("sessionID").getText(); elem.addAttribute("sessionID", sessionID); // Check if a users session has expired Element sessionExpired = iq.element("expired"); if (sessionExpired != null) { siteUsers.remove(sessionID); elem.addElement("sessionExpired").setText("true"); for (AgentSession session : workgroup.getAgentSessions()) { update.setTo(session.getJID()); update.setType(IQ.Type.set); workgroup.send(update); } reply = IQ.createResultIQ(packet); workgroup.send(reply); return; } Element chatting = iq.element("chatting"); if (chatting != null) { elem.addElement("chatting").setText("true"); for (AgentSession session : workgroup.getAgentSessions()) { update.setTo(session.getJID()); update.setType(IQ.Type.set); workgroup.send(update); } reply = IQ.createResultIQ(packet); workgroup.send(reply); return; } // Check if user left a page Element leaving = iq.element("leftPage"); if (leaving != null) { elem.addElement("leftPage").setText("true"); for (AgentSession session : workgroup.getAgentSessions()) { update.setTo(session.getJID()); update.setType(IQ.Type.set); workgroup.send(update); } reply = IQ.createResultIQ(packet); workgroup.send(reply); // Handle pageView SiteUser siteUser = siteUsers.get(sessionID); if (siteUser != null) { PageView lastView = siteUser.getLastView(); if (lastView != null) { lastView.setEndTime(new Date()); } } return; } // If user has not left a page and the session has not expired. This user // has entered a new page. String url = iq.element("url").getTextTrim(); String title = iq.element("title").getTextTrim(); String referrer = iq.element("referrer").getTextTrim(); String ipAddress = iq.element("ipAddress").getTextTrim(); String userID = iq.element("userID").getTextTrim(); // Send back reply reply = IQ.createResultIQ(packet); workgroup.send(reply); elem.addElement("url").setText(url); elem.addElement("title").setText(title); elem.addElement("referrer").setText(referrer); elem.addElement("userID").setText(userID); elem.addElement("ipAddress").setText(ipAddress); // Add to tracking information SiteUser siteUser = siteUsers.get(sessionID); if (siteUser == null) { siteUser = new SiteUser(); } PageView pageView = new PageView(); pageView.setStartTime(new Date()); pageView.setTitle(title); pageView.setUrl(url); siteUser.addView(pageView); siteUser.setJID(reply.getTo()); siteUsers.put(sessionID, siteUser); for (AgentSession session : workgroup.getAgentSessions()) { update.setTo(session.getJID()); update.setType(IQ.Type.set); workgroup.send(update); } } private void handleInvitation(IQ packet, Workgroup workgroup) { Element iq = packet.getChildElement(); // Define default values IQ update = new IQ(); Element elem = update.setChildElement("site-invite", "http://jivesoftware.com/protocol/workgroup"); String sessionID = iq.attribute("sessionID").getText(); elem.addAttribute("sessionID", sessionID); SiteUser siteUser = siteUsers.get(sessionID); IQ reply = IQ.createResultIQ(packet); if (siteUser == null) { reply.setChildElement(packet.getChildElement().createCopy()); reply.setError(new PacketError(PacketError.Condition.item_not_found)); workgroup.send(reply); return; } else { // Send back reply workgroup.send(reply); } String agent = iq.element("agent").getText(); String message = iq.element("message").getText(); elem.addElement("agent").setText(agent); elem.addElement("message").setText(message); update.setTo(siteUser.getJID()); update.setType(IQ.Type.set); workgroup.send(update); } private class SiteUser { private List<PageView> views = new ArrayList<PageView>(); private JID jid = null; public void addView(PageView view) { views.add(view); } public void setJID(JID jid) { this.jid = jid; } public JID getJID() { return jid; } public Collection<PageView> getViews() { return views; } public PageView getLastView() { if (views.size() > 0) { return views.get(views.size() - 1); } return null; } } private class PageView { private String url; private String title; private Date startTime; private Date endTime; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public long getTimeViewed() { if (startTime != null) { long start = startTime.getTime(); long end = endTime != null ? endTime.getTime() : 0; if (end == 0) { return new Date().getTime() - start; } else { return end - start; } } return 0; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } } }