package com.rayo.client.xmpp.stanza;
import org.dom4j.Element;
import com.rayo.client.util.JID;
import com.rayo.client.util.JIDImpl;
import com.rayo.client.xmpp.extensions.Extension;
/**
* A stanza is the base class for every message in rayo. It is backed by a Dom4j element.
*
* There is three different type of stanzas:
*
* <ul>
* <li>{@link Message} -- used to send data between users.
* <li>{@link Presence} -- contains user presence information or is used
* to manage presence subscriptions.
* <li>{@link IQ} -- exchange information and perform queries using a
* request/response protocol.
* </ul>
*
* @author martin
*
*/
public abstract class Stanza<T extends XmppObject> extends AbstractXmppObject {
/**
* Creates an empty Stanza element.
*/
public Stanza() {
super();
}
public Stanza(String namespace) {
super(namespace);
}
/**
* Constructs a new Stanza using the given DOM element as data.
*
* @param element DOM element to backup
*/
public Stanza(Element element) {
super(element);
}
public Stanza(XmppObject xmppObject) {
super(xmppObject);
}
public String getFrom() {
//TODO: Lots of stuff. Caching,Stringprep, nodeprep, etc.
return attribute("from");
}
public T setFrom(String from) {
setAttribute("from", from);
return asGeneric();
}
public String getTo() {
//TODO: Lots of stuff. Caching,Stringprep, nodeprep, etc.
return attribute("to");
}
public JID getFromJid() {
return new JIDImpl(getFrom());
}
public JID getToJid() {
return new JIDImpl(getTo());
}
public T setTo(String to) {
setAttribute("to", to);
return asGeneric();
}
public T setId(String id) {
setAttribute("id", id);
return asGeneric();
}
/**
* Reverses this Stanza. This method will swap the values of the 'to' and 'from' fields.
*
* @return Stanza with the values swapped
*/
public T reverse() {
String from = getFrom();
setFrom(getTo());
setTo(from);
return asGeneric();
}
@SuppressWarnings("unchecked")
private T asGeneric() {
return (T)this;
}
/**
* Sets the packet error using the specified condition. Calling this
* method will automatically set the packet "type" attribute to "error".
* This is a convenience method equivalent to calling:
*
* <tt>setError(new PacketError(condition));</tt>
*
* @param condition the error condition.
*/
public void setError(Error.Condition condition) {
setError(new Error(condition));
}
public void setType(String type) {
setAttribute("type", type);
}
public String getRawType() {
return attribute("type");
}
public T error(Error.Condition condition) {
setError(new Error(condition));
return asGeneric();
}
public T error(Error.Condition condition, Error.Type type) {
setError(new Error(condition,type));
return asGeneric();
}
public T setChild(Extension extension) {
set(extension);
return (T)this;
}
public T addChild(XmppObject child) {
add(child);
return (T)this;
}
/**
* Sets the child of this IQ object.
*
* @param child Child XMPP Object
*
* @return {@link AbstractXmppObject} Child XMPP object
*/
public T setChild(XmppObject child) {
clearChildren();
set(child);
return (T)this;
}
public boolean hasExtension() {
Element element = getFirstChild();
if (element == null) {
return false;
}
// Compare with known IQ extensions
if (element.getName().equals(Error.NAME) ||
element.getName().equals(Bind.NAME) ||
element.getName().equals(Query.NAME) ||
element.getName().equals(Session.NAME)) {
return false;
}
return true;
}
public Extension getExtension() {
return new Extension(getFirstChild());
}
}