KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > messenger > muc > HistoryRequest


1 /**
2  * $RCSfile: HistoryRequest.java,v $
3  * $Revision: 1.9 $
4  * $Date: 2005/07/28 00:13:58 $
5  *
6  * Copyright (C) 2004 Jive Software. All rights reserved.
7  *
8  * This software is published under the terms of the GNU Public License (GPL),
9  * a copy of which is included in this distribution.
10  */

11
12 package org.jivesoftware.messenger.muc;
13
14 import java.text.DateFormat JavaDoc;
15 import java.text.ParseException JavaDoc;
16 import java.text.SimpleDateFormat JavaDoc;
17 import java.util.Date JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.LinkedList JavaDoc;
20 import java.util.ListIterator JavaDoc;
21 import java.util.TimeZone JavaDoc;
22
23 import org.jivesoftware.messenger.muc.spi.MUCRoleImpl;
24 import org.jivesoftware.util.Log;
25 import org.jivesoftware.util.JiveConstants;
26 import org.dom4j.Element;
27 import org.xmpp.packet.Message;
28
29 /**
30  * Represents the amount of history requested by an occupant while joining a room. There are
31  * basically four ways to control the amount of history that a user may receive. Those are: limit
32  * by the maximum limit of characters to receive, limit by a maximum number of stanzas to receive,
33  * limit to receive only the messages before a given date or of the last X seconds.<p>
34  *
35  * A user may combine any of these four methods. The idea is that the user will receive the smallest
36  * amount of traffic so the amount of history to collect will stop as soon as any of the requested
37  * method has reached its limit.
38  *
39  * @author Gaston Dombiak
40  */

41 public class HistoryRequest {
42
43     private static final DateFormat JavaDoc formatter = new SimpleDateFormat JavaDoc(JiveConstants.XMPP_DATETIME_FORMAT);
44     private static final DateFormat JavaDoc delayedFormatter = new SimpleDateFormat JavaDoc("yyyyMMdd'T'HH:mm:ss");
45     static {
46         delayedFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
47         formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
48     }
49
50     private int maxChars = -1;
51     private int maxStanzas = -1;
52     private int seconds = -1;
53     private Date JavaDoc since;
54
55     public HistoryRequest(Element userFragment) {
56         Element history = userFragment.element("history");
57         if (history != null) {
58             if (history.attribute("maxchars") != null) {
59                 this.maxChars = Integer.parseInt(history.attributeValue("maxchars"));
60             }
61             if (history.attribute("maxstanzas") != null) {
62                 this.maxStanzas = Integer.parseInt(history.attributeValue("maxstanzas"));
63             }
64             if (history.attribute("seconds") != null) {
65                 this.seconds = Integer.parseInt(history.attributeValue("seconds"));
66             }
67             if (history.attribute("since") != null) {
68                 try {
69                     // parse utc into Date
70
this.since = formatter.parse(history.attributeValue("since"));
71                 }
72                 catch(ParseException JavaDoc pe) {
73                     Log.error("Error parsing date from history management", pe);
74                     this.since = null;
75                 }
76             }
77         }
78     }
79     
80     /**
81      * Returns the total number of characters to receive in the history.
82      *
83      * @return total number of characters to receive in the history.
84      */

85     public int getMaxChars() {
86         return maxChars;
87     }
88
89     /**
90      * Returns the total number of messages to receive in the history.
91      *
92      * @return the total number of messages to receive in the history.
93      */

94     public int getMaxStanzas() {
95         return maxStanzas;
96     }
97
98     /**
99      * Returns the number of seconds to use to filter the messages received during that time.
100      * In other words, only the messages received in the last "X" seconds will be included in
101      * the history.
102      *
103      * @return the number of seconds to use to filter the messages received during that time.
104      */

105     public int getSeconds() {
106         return seconds;
107     }
108
109     /**
110      * Returns the since date to use to filter the messages received during that time.
111      * In other words, only the messages received since the datetime specified will be
112      * included in the history.
113      *
114      * @return the since date to use to filter the messages received during that time.
115      */

116     public Date JavaDoc getSince() {
117         return since;
118     }
119
120     /**
121      * Returns true if the history has been configured with some values.
122      *
123      * @return true if the history has been configured with some values.
124      */

125     private boolean isConfigured() {
126         return maxChars > -1 || maxStanzas > -1 || seconds > -1 || since != null;
127     }
128
129     /**
130      * Sends the smallest amount of traffic that meets any combination of the requested criteria.
131      *
132      * @param joinRole the user that will receive the history.
133      * @param roomHistory the history of the room.
134      */

135     public void sendHistory(MUCRoleImpl joinRole, MUCRoomHistory roomHistory) {
136         if (!isConfigured()) {
137             Iterator JavaDoc history = roomHistory.getMessageHistory();
138             while (history.hasNext()) {
139                 joinRole.send((Message) history.next());
140             }
141         }
142         else {
143             if (getMaxChars() == 0) {
144                 // The user requested to receive no history
145
return;
146             }
147             Message message;
148             int accumulatedChars = 0;
149             int accumulatedStanzas = 0;
150             Element delayInformation;
151             LinkedList JavaDoc historyToSend = new LinkedList JavaDoc();
152             ListIterator JavaDoc iterator = roomHistory.getReverseMessageHistory();
153             while (iterator.hasPrevious()) {
154                 message = (Message)iterator.previous();
155                 // Update number of characters to send
156
String JavaDoc text = message.getBody() == null ? message.getSubject() : message.getBody();
157                 accumulatedChars += text.length();
158                 if (getMaxChars() > -1 && accumulatedChars > getMaxChars()) {
159                     // Stop collecting history since we have exceded a limit
160
break;
161                 }
162                 // Update number of messages to send
163
accumulatedStanzas ++;
164                 if (getMaxStanzas() > -1 && accumulatedStanzas > getMaxStanzas()) {
165                     // Stop collecting history since we have exceded a limit
166
break;
167                 }
168
169                 if (getSeconds() > -1 || getSince() != null) {
170                     delayInformation = message.getChildElement("x", "jabber:x:delay");
171                     try {
172                         // Get the date when the historic message was sent
173
Date JavaDoc delayedDate = delayedFormatter.parse(delayInformation.attributeValue("stamp"));
174                         if (getSince() != null && delayedDate.before(getSince())) {
175                             // Stop collecting history since we have exceded a limit
176
break;
177                         }
178                         if (getSeconds() > -1) {
179                             Date JavaDoc current = new Date JavaDoc();
180                             long diff = (current.getTime() - delayedDate.getTime()) / 1000;
181                             if (getSeconds() <= diff) {
182                                 // Stop collecting history since we have exceded a limit
183
break;
184                             }
185                         }
186                     }
187                     catch (Exception JavaDoc e) {
188                         Log.error("Error parsing date from historic message", e);
189                     }
190
191                 }
192
193                 historyToSend.addFirst(message);
194             }
195             // Send the smallest amount of traffic to the user
196
Iterator JavaDoc history = historyToSend.iterator();
197             while (history.hasNext()) {
198                 joinRole.send((Message) history.next());
199             }
200         }
201     }
202 }
203
Popular Tags