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