1/**
2 * $RCSfile$
3 * $Revision: 2407 $
4 * $Date: 2004-11-02 15:37:00 -0800 (Tue, 02 Nov 2004) $
5 *
6 * Copyright 2003-2007 Jive Software.
7 *
8 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *     http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21package org.jivesoftware.smackx.packet;
22
23import java.io.IOException;
24
25import org.jivesoftware.smack.PacketCollector;
26import org.jivesoftware.smack.SmackConfiguration;
27import org.jivesoftware.smack.Connection;
28import org.jivesoftware.smack.XMPPException;
29import org.jivesoftware.smack.filter.PacketIDFilter;
30import org.jivesoftware.smack.packet.IQ;
31import org.jivesoftware.smack.provider.IQProvider;
32import org.jivesoftware.smack.util.StringUtils;
33import org.xmlpull.v1.XmlPullParser;
34import org.xmlpull.v1.XmlPullParserException;
35
36/**
37 * A last activity IQ for retrieving information about the last activity associated with a Jabber ID.
38 * LastActivity (XEP-0012) allows for retrieval of how long a particular user has been idle and the
39 * message the specified when doing so. Use {@link org.jivesoftware.smackx.LastActivityManager}
40 * to get the last activity of a user.
41 *
42 * @author Derek DeMoro
43 */
44public class LastActivity extends IQ {
45
46    public static final String NAMESPACE = "jabber:iq:last";
47
48    public long lastActivity = -1;
49    public String message;
50
51    public LastActivity() {
52        setType(IQ.Type.GET);
53    }
54
55    public String getChildElementXML() {
56        StringBuilder buf = new StringBuilder();
57        buf.append("<query xmlns=\"" + NAMESPACE + "\"");
58        if (lastActivity != -1) {
59            buf.append(" seconds=\"").append(lastActivity).append("\"");
60        }
61        buf.append("></query>");
62        return buf.toString();
63    }
64
65
66    public void setLastActivity(long lastActivity) {
67        this.lastActivity = lastActivity;
68    }
69
70
71    private void setMessage(String message) {
72        this.message = message;
73    }
74
75    /**
76     * Returns number of seconds that have passed since the user last logged out.
77     * If the user is offline, 0 will be returned.
78     *
79     * @return the number of seconds that have passed since the user last logged out.
80     */
81    public long getIdleTime() {
82        return lastActivity;
83    }
84
85
86    /**
87     * Returns the status message of the last unavailable presence received from the user.
88     *
89     * @return the status message of the last unavailable presence received from the user
90     */
91    public String getStatusMessage() {
92        return message;
93    }
94
95
96    /**
97     * The IQ Provider for LastActivity.
98     *
99     * @author Derek DeMoro
100     */
101    public static class Provider implements IQProvider {
102
103        public Provider() {
104            super();
105        }
106
107        public IQ parseIQ(XmlPullParser parser) throws XMPPException, XmlPullParserException {
108            if (parser.getEventType() != XmlPullParser.START_TAG) {
109                throw new XMPPException("Parser not in proper position, or bad XML.");
110            }
111
112            LastActivity lastActivity = new LastActivity();
113            String seconds = parser.getAttributeValue("", "seconds");
114            String message = null;
115            try {
116                message = parser.nextText();
117            } catch (IOException e1) {
118                // Ignore
119            }
120            if (seconds != null) {
121                try {
122                    lastActivity.setLastActivity(Long.parseLong(seconds));
123                } catch (NumberFormatException e) {
124                    // Ignore
125                }
126            }
127
128            if (message != null) {
129                lastActivity.setMessage(message);
130            }
131            return lastActivity;
132        }
133    }
134
135    /**
136     * Retrieve the last activity of a particular jid.
137     * @param con the current Connection.
138     * @param jid the JID of the user.
139     * @return the LastActivity packet of the jid.
140     * @throws XMPPException thrown if a server error has occured.
141     * @deprecated This method only retreives the lapsed time since the last logout of a particular jid.
142     * Replaced by {@link  org.jivesoftware.smackx.LastActivityManager#getLastActivity(Connection, String)  getLastActivity}
143     */
144    public static LastActivity getLastActivity(Connection con, String jid) throws XMPPException {
145        LastActivity activity = new LastActivity();
146        jid = StringUtils.parseBareAddress(jid);
147        activity.setTo(jid);
148
149        PacketCollector collector = con.createPacketCollector(new PacketIDFilter(activity.getPacketID()));
150        con.sendPacket(activity);
151
152        LastActivity response = (LastActivity) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
153
154        // Cancel the collector.
155        collector.cancel();
156        if (response == null) {
157            throw new XMPPException("No response from server on status set.");
158        }
159        if (response.getError() != null) {
160            throw new XMPPException(response.getError());
161        }
162        return response;
163    }
164}
165