KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xmpp > packet > Packet


1 /**
2  * $RCSfile: Packet.java,v $
3  * $Revision: 1.16 $
4  * $Date: 2005/07/08 18:11:02 $
5  *
6  * Copyright 2004 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
21 package org.xmpp.packet;
22
23 import org.dom4j.DocumentFactory;
24 import org.dom4j.Element;
25 import org.dom4j.QName;
26 import org.dom4j.io.OutputFormat;
27 import org.dom4j.io.XMLWriter;
28
29 import java.io.StringWriter JavaDoc;
30 import java.lang.reflect.Constructor JavaDoc;
31 import java.util.List JavaDoc;
32
33 /**
34  * An XMPP packet (also referred to as a stanza). Each packet is backed by a
35  * DOM4J Element. A set of convenience methods allows easy manipulation of
36  * the Element, or the Element can be accessed directly and manipulated.<p>
37  *
38  * There are three core packet types:<ul>
39  * <li>{@link Message} -- used to send data between users.
40  * <li>{@link Presence} -- contains user presence information or is used
41  * to manage presence subscriptions.
42  * <li>{@link IQ} -- exchange information and perform queries using a
43  * request/response protocol.
44  * </ul>
45  *
46  * @author Matt Tucker
47  */

48 public abstract class Packet {
49
50     protected static DocumentFactory docFactory = DocumentFactory.getInstance();
51
52     protected Element element;
53
54     /**
55      * Constructs a new Packet.
56      *
57      * @param element the XML Element that contains the packet contents.
58      */

59     public Packet(Element element) {
60         this.element = element;
61         // Apply stringprep profiles to the "to" and "from" values.
62
String JavaDoc to = element.attributeValue("to");
63         if (to != null) {
64             JID toJID = new JID(to);
65             element.addAttribute("to", toJID.toString());
66         }
67         String JavaDoc from = element.attributeValue("from");
68         if (from != null) {
69             JID fromJID = new JID(from);
70             element.addAttribute("from", fromJID.toString());
71         }
72     }
73
74     /**
75      * Constructs a new Packet with no element data. This method is used by
76      * extensions of this class that require a more optimized path for creating
77      * new packets.
78      */

79     protected Packet() {
80
81     }
82
83     /**
84      * Returns the packet ID, or <tt>null</tt> if the packet does not have an ID.
85      * Packet ID's are optional, except for IQ packets.
86      *
87      * @return the packet ID.
88      */

89     public String JavaDoc getID() {
90         return element.attributeValue("id");
91     }
92
93     /**
94      * Sets the packet ID. Packet ID's are optional, except for IQ packets.
95      *
96      * @param ID the packet ID.
97      */

98     public void setID(String JavaDoc ID) {
99         element.addAttribute("id", ID);
100     }
101
102     /**
103      * Returns the XMPP address (JID) that the packet is addressed to, or <tt>null</tt>
104      * if the "to" attribute is not set. The XMPP protocol often makes the "to"
105      * attribute optional, so it does not always need to be set.
106      *
107      * @return the XMPP address (JID) that the packet is addressed to, or <tt>null</tt>
108      * if not set.
109      */

110     public JID getTo() {
111         String JavaDoc to = element.attributeValue("to");
112         if (to == null) {
113             return null;
114         }
115         else {
116             // Return a new JID that bypasses stringprep profile checking.
117
// This improves speed and is safe as long as the user doesn't
118
// directly manipulate the attributes of the underlying Element
119
// that represent JID's.
120
return new JID(to, null);
121         }
122     }
123
124     /**
125      * Sets the XMPP address (JID) that the packet is addressed to. The XMPP protocol
126      * often makes the "to" attribute optional, so it does not always need to be set.
127      *
128      * @param to the XMPP address (JID) that the packet is addressed to.
129      */

130     public void setTo(String JavaDoc to) {
131         // Apply stringprep profiles to value.
132
if (to != null) {
133             to = new JID(to).toString();
134         }
135         element.addAttribute("to", to);
136     }
137
138     /**
139      * Sets the XMPP address (JID) that the packet is address to. The XMPP protocol
140      * often makes the "to" attribute optional, so it does not always need to be set.
141      *
142      * @param to the XMPP address (JID) that the packet is addressed to.
143      */

144     public void setTo(JID to) {
145         if (to == null) {
146             element.addAttribute("to", null);
147         }
148         else {
149             element.addAttribute("to", to.toString());
150         }
151     }
152
153     /**
154      * Returns the XMPP address (JID) that the packet is from, or <tt>null</tt>
155      * if the "from" attribute is not set. The XMPP protocol often makes the "from"
156      * attribute optional, so it does not always need to be set.
157      *
158      * @return the XMPP address that the packet is from, or <tt>null</tt>
159      * if not set.
160      */

161     public JID getFrom() {
162         String JavaDoc from = element.attributeValue("from");
163         if (from == null) {
164             return null;
165         }
166         else {
167             // Return a new JID that bypasses stringprep profile checking.
168
// This improves speed and is safe as long as the user doesn't
169
// directly manipulate the attributes of the underlying Element
170
// that represent JID's.
171
return new JID(from, null);
172         }
173     }
174
175     /**
176      * Sets the XMPP address (JID) that the packet comes from. The XMPP protocol
177      * often makes the "from" attribute optional, so it does not always need to be set.
178      *
179      * @param from the XMPP address (JID) that the packet comes from.
180      */

181     public void setFrom(String JavaDoc from) {
182         // Apply stringprep profiles to value.
183
if (from != null) {
184             from = new JID(from).toString();
185         }
186         element.addAttribute("from", from);
187     }
188
189     /**
190      * Sets the XMPP address (JID) that the packet comes from. The XMPP protocol
191      * often makes the "from" attribute optional, so it does not always need to be set.
192      *
193      * @param from the XMPP address (JID) that the packet comes from.
194      */

195     public void setFrom(JID from) {
196         if (from == null) {
197             element.addAttribute("from", null);
198         }
199         else {
200             element.addAttribute("from", from.toString());
201         }
202     }
203
204     /**
205      * Adds the element contained in the PacketExtension to the element of this packet.
206      * It is important that this is the first and last time the element contained in
207      * PacketExtension is added to another Packet. Otherwise, a runtime error will be
208      * thrown when trying to add the PacketExtension's element to the Packet's element.
209      * Future modifications to the PacketExtension will be reflected in this Packet.
210      *
211      * @param extension the PacketExtension whose element will be added to this Packet's element.
212      */

213     public void addExtension(PacketExtension extension) {
214         element.add(extension.getElement());
215     }
216
217     /**
218      * Returns a {@link PacketExtension} on the first element found in this packet
219      * for the specified <tt>name</tt> and <tt>namespace</tt> or <tt>null</tt> if
220      * none was found.
221      *
222      * @param name the child element name.
223      * @param namespace the child element namespace.
224      * @return a PacketExtension on the first element found in this packet for the specified
225      * name and namespace or null if none was found.
226      */

227     public PacketExtension getExtension(String JavaDoc name, String JavaDoc namespace) {
228         List JavaDoc extensions = element.elements(QName.get(name, namespace));
229         if (!extensions.isEmpty()) {
230             Class JavaDoc extensionClass = PacketExtension.getExtensionClass(name, namespace);
231             if (extensionClass != null) {
232                 try {
233                     Constructor JavaDoc constructor = extensionClass.getDeclaredConstructor(new Class JavaDoc[]{
234                         Element.class});
235                     return (PacketExtension) constructor.newInstance(new Object JavaDoc[]{
236                         extensions.get(0)});
237                 } catch (Exception JavaDoc e) {
238                 }
239             }
240         }
241         return null;
242     }
243
244     /**
245      * Deletes the first element whose element name and namespace matches the specified
246      * element name and namespace.<p>
247      *
248      * Notice that this method may remove any child element that matches the specified
249      * element name and namespace even if that element was not added to the Packet using a
250      * {@link PacketExtension}.
251      *
252      *
253      * @param name the child element name.
254      * @param namespace the child element namespace.
255      * @return true if a child element was removed.
256      */

257     public boolean deleteExtension(String JavaDoc name, String JavaDoc namespace) {
258         List JavaDoc extensions = element.elements(QName.get(name, namespace));
259         if (!extensions.isEmpty()) {
260             element.remove((Element) extensions.get(0));
261             return true;
262         }
263         return false;
264     }
265
266     /**
267      * Returns the packet error, or <tt>null</tt> if there is no packet error.
268      *
269      * @return the packet error.
270      */

271     public PacketError getError() {
272         Element error = element.element("error");
273         if (error != null) {
274             return new PacketError(element);
275         }
276         return null;
277     }
278
279     /**
280      * Sets the packet error. Calling this method will automatically set
281      * the packet "type" attribute to "error".
282      *
283      * @param error the packet error.
284      */

285     public void setError(PacketError error) {
286         if (element == null) {
287             throw new NullPointerException JavaDoc("Error cannot be null");
288         }
289         // Force the packet type to "error".
290
element.addAttribute("type", "error");
291         // Remove an existing error packet.
292
if (element.element("error") != null) {
293             element.remove(element.element("error"));
294         }
295         // Add the error element.
296
element.add(error.getElement());
297     }
298
299     /**
300      * Sets the packet error using the specified condition. Calling this
301      * method will automatically set the packet "type" attribute to "error".
302      * This is a convenience method equivalent to calling:
303      *
304      * <tt>setError(new PacketError(condition));</tt>
305      *
306      * @param condition the error condition.
307      */

308     public void setError(PacketError.Condition condition) {
309        setError(new PacketError(condition));
310     }
311
312     /**
313      * Creates a deep copy of this packet.
314      *
315      * @return a deep copy of this packet.
316      */

317     public abstract Packet createCopy();
318
319     /**
320      * Returns the DOM4J Element that backs the packet. The element is the definitive
321      * representation of the packet and can be manipulated directly to change
322      * packet contents.
323      *
324      * @return the DOM4J Element that represents the packet.
325      */

326     public Element getElement() {
327         return element;
328     }
329
330     /**
331      * Returns the textual XML representation of this packet.
332      *
333      * @return the textual XML representation of this packet.
334      */

335     public String JavaDoc toXML() {
336         return element.asXML();
337     }
338
339     public String JavaDoc toString() {
340         StringWriter JavaDoc out = new StringWriter JavaDoc();
341         XMLWriter writer = new XMLWriter(out, OutputFormat.createPrettyPrint());
342         try {
343             writer.write(element);
344         }
345         catch (Exception JavaDoc e) { }
346         return out.toString();
347     }
348 }
Popular Tags