001/**
002 *
003 * Copyright 2003-2007 Jive Software.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.jivesoftware.smackx.offline.packet;
019
020import java.io.IOException;
021import java.util.ArrayList;
022import java.util.Collections;
023import java.util.List;
024
025import org.jivesoftware.smack.packet.IQ;
026import org.jivesoftware.smack.packet.IqData;
027import org.jivesoftware.smack.packet.XmlEnvironment;
028import org.jivesoftware.smack.provider.IqProvider;
029import org.jivesoftware.smack.xml.XmlPullParser;
030import org.jivesoftware.smack.xml.XmlPullParserException;
031
032import org.jivesoftware.smackx.offline.OfflineMessageManager;
033
034/**
035 * Represents a request to get some or all the offline messages of a user. This class can also
036 * be used for deleting some or all the offline messages of a user.
037 *
038 * @author Gaston Dombiak
039 */
040public class OfflineMessageRequest extends IQ {
041
042    public static final String ELEMENT = "offline";
043    public static final String NAMESPACE = OfflineMessageManager.NAMESPACE;
044
045    private final List<Item> items = new ArrayList<>();
046    private boolean purge = false;
047    private boolean fetch = false;
048
049    public OfflineMessageRequest() {
050        super(ELEMENT, NAMESPACE);
051    }
052
053    /**
054     * Returns a List of item children that holds information about offline messages to
055     * view or delete.
056     *
057     * @return a List of item children that holds information about offline messages to
058     *         view or delete.
059     */
060    public List<Item> getItems() {
061        synchronized (items) {
062            return Collections.unmodifiableList(new ArrayList<>(items));
063        }
064    }
065
066    /**
067     * Adds an item child that holds information about offline messages to view or delete.
068     *
069     * @param item the item child that holds information about offline messages to view or delete.
070     */
071    public void addItem(Item item) {
072        synchronized (items) {
073            items.add(item);
074        }
075    }
076
077    /**
078     * Returns true if all the offline messages of the user should be deleted.
079     *
080     * @return true if all the offline messages of the user should be deleted.
081     */
082    public boolean isPurge() {
083        return purge;
084    }
085
086    /**
087     * Sets if all the offline messages of the user should be deleted.
088     *
089     * @param purge true if all the offline messages of the user should be deleted.
090     */
091    public void setPurge(boolean purge) {
092        this.purge = purge;
093    }
094
095    /**
096     * Returns true if all the offline messages of the user should be retrieved.
097     *
098     * @return true if all the offline messages of the user should be retrieved.
099     */
100    public boolean isFetch() {
101        return fetch;
102    }
103
104    /**
105     * Sets if all the offline messages of the user should be retrieved.
106     *
107     * @param fetch true if all the offline messages of the user should be retrieved.
108     */
109    public void setFetch(boolean fetch) {
110        this.fetch = fetch;
111    }
112
113    @Override
114    protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) {
115        buf.rightAngleBracket();
116
117        synchronized (items) {
118            for (Item item : items) {
119                buf.append(item.toXML());
120            }
121        }
122        if (purge) {
123            buf.append("<purge/>");
124        }
125        if (fetch) {
126            buf.append("<fetch/>");
127        }
128
129        return buf;
130    }
131
132    /**
133     * Item child that holds information about offline messages to view or delete.
134     *
135     * @author Gaston Dombiak
136     */
137    public static class Item {
138        private String action;
139        private String jid;
140        private String node;
141
142        /**
143         * Creates a new item child.
144         *
145         * @param node the actor's affiliation to the room
146         */
147        public Item(String node) {
148            this.node = node;
149        }
150
151        public String getNode() {
152            return node;
153        }
154
155        /**
156         * Returns "view" or "remove" that indicate if the server should return the specified
157         * offline message or delete it.
158         *
159         * @return "view" or "remove" that indicate if the server should return the specified
160         *         offline message or delete it.
161         */
162        public String getAction() {
163            return action;
164        }
165
166        /**
167         * Sets if the server should return the specified offline message or delete it. Possible
168         * values are "view" or "remove".
169         *
170         * @param action if the server should return the specified offline message or delete it.
171         */
172        public void setAction(String action) {
173            this.action = action;
174        }
175
176        public String getJid() {
177            return jid;
178        }
179
180        public void setJid(String jid) {
181            this.jid = jid;
182        }
183
184        public String toXML() {
185            StringBuilder buf = new StringBuilder();
186            buf.append("<item");
187            if (getAction() != null) {
188                buf.append(" action=\"").append(getAction()).append('"');
189            }
190            if (getJid() != null) {
191                buf.append(" jid=\"").append(getJid()).append('"');
192            }
193            if (getNode() != null) {
194                buf.append(" node=\"").append(getNode()).append('"');
195            }
196            buf.append("/>");
197            return buf.toString();
198        }
199    }
200
201    public static class Provider extends IqProvider<OfflineMessageRequest> {
202
203        @Override
204        public OfflineMessageRequest parse(XmlPullParser parser,
205                        int initialDepth, IqData iqData, XmlEnvironment xmlEnvironment) throws XmlPullParserException,
206                        IOException {
207            OfflineMessageRequest request = new OfflineMessageRequest();
208            boolean done = false;
209            while (!done) {
210                XmlPullParser.Event eventType = parser.next();
211                if (eventType == XmlPullParser.Event.START_ELEMENT) {
212                    if (parser.getName().equals("item")) {
213                        request.addItem(parseItem(parser));
214                    }
215                    else if (parser.getName().equals("purge")) {
216                        request.setPurge(true);
217                    }
218                    else if (parser.getName().equals("fetch")) {
219                        request.setFetch(true);
220                    }
221                } else if (eventType == XmlPullParser.Event.END_ELEMENT) {
222                    if (parser.getName().equals("offline")) {
223                        done = true;
224                    }
225                }
226            }
227
228            return request;
229        }
230
231        private static Item parseItem(XmlPullParser parser)
232                        throws XmlPullParserException, IOException {
233            boolean done = false;
234            Item item = new Item(parser.getAttributeValue("", "node"));
235            item.setAction(parser.getAttributeValue("", "action"));
236            item.setJid(parser.getAttributeValue("", "jid"));
237            while (!done) {
238                XmlPullParser.Event eventType = parser.next();
239                if (eventType == XmlPullParser.Event.END_ELEMENT) {
240                    if (parser.getName().equals("item")) {
241                        done = true;
242                    }
243                }
244            }
245            return item;
246        }
247    }
248}