package com.sissi.protocol.message;
import java.util.UUID;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import com.sissi.io.read.Collector;
import com.sissi.io.read.Metadata;
import com.sissi.protocol.Protocol;
import com.sissi.protocol.ProtocolType;
import com.sissi.protocol.error.ServerError;
import com.sissi.protocol.iq.data.XData;
import com.sissi.protocol.iq.data.XDataType;
import com.sissi.protocol.iq.data.XField;
import com.sissi.protocol.muc.XUser;
import com.sissi.protocol.offline.Delay;
import com.sissi.protocol.offline.History;
/**
* @author kim 2013-10-27
*/
@Metadata(uri = Message.XMLNS, localName = Message.NAME)
@XmlRootElement
public class Message extends Protocol implements Collector {
public final static String XMLNS = "jabber:client";
public final static String NAME = "message";
private boolean trace;
private Body body;
private XUser user;
private XData data;
private Delay delay;
private Thread thread;
private Subject subject;
private History history;
private AckRequest request;
private AckReceived received;
public Message() {
this.trace = true;
}
private Message history(History history) {
this.history = history;
return this;
}
private Message request(AckRequest request) {
this.request = request;
return this;
}
private Message received(AckReceived received) {
this.received = received;
return this;
}
private Message x(Object x) {
return XData.class == x.getClass() ? this.data(XData.class.cast(x)) : this.muc(XUser.class.cast(x));
}
public Message setType(MessageType type) {
super.setType(type.toString());
return this;
}
public String getType() {
return super.getType() != null ? super.getType() : MessageType.NONE.toString();
}
public boolean type(MessageType... types) {
for (MessageType type : types) {
if (type.equals(this.getType())) {
return true;
}
}
return false;
}
public String getId() {
return super.getId() != null || this.type(ProtocolType.ERROR, ProtocolType.RESULT) ? super.getId() : super.setId(UUID.randomUUID().toString()).getId();
}
public boolean delay() {
return this.getDelay() != null;
}
@XmlElement
public Delay getDelay() {
return this.delay;
}
public Message delay(Delay delay) {
this.delay = this.delay != null ? this.delay : delay;
return this;
}
public boolean body() {
return this.getBody() != null;
}
public Message body(String body) {
this.body = body != null ? new Body(body) : null;
return this;
}
public Message body(Body body) {
this.body = body;
return this;
}
@XmlElement
public Body getBody() {
return this.body;
}
public String thread() {
return this.getThread() != null ? this.getThread().getText() : null;
}
public Message noneThread() {
this.trace = false;
return this;
}
public Message thread(Thread thread) {
this.thread = thread;
return this;
}
public Message setThread(String thread) {
this.thread = thread != null ? new Thread(thread) : null;
return this;
}
@XmlElement
public Thread getThread() {
return this.thread != null && this.thread.content() ? this.thread : (this.trace ? new Thread(UUID.randomUUID().toString()) : null);
}
public boolean subject() {
return this.getSubject() != null;
}
public Message subject(String subject) {
this.subject = subject != null ? new Subject(subject) : null;
return this;
}
public Message subject(Subject subject) {
this.subject = subject;
return this;
}
@XmlElement
public Subject getSubject() {
return this.subject != null && this.subject.content() ? this.subject : null;
}
@XmlElement
public ServerError getError() {
return super.getError();
}
public Message muc(XUser x) {
this.user = x;
return this;
}
@XmlElement(name = XUser.NAME)
public XUser getMuc() {
return this.user;
}
public boolean data(String name) {
return this.getData() != null && this.getData().findField(name, XField.class) != null;
}
public boolean dataType(String type) {
return this.getData() != null && this.getData().type(XDataType.parse(type));
}
public Message data(XData x) {
this.data = x;
return this;
}
@XmlElement(name = XData.NAME)
public XData getData() {
return this.data;
}
public boolean invite() {
return this.getMuc() != null && this.getMuc().invite();
}
public boolean decline() {
return this.getMuc() != null && this.getMuc().decline();
}
public boolean request() {
return this.getRequest() != null;
}
public Message request(boolean request) {
return this.request(request ? AckRequest.REQUEST : null);
}
@XmlElement(name = AckRequest.NAME)
public AckRequest getRequest() {
return this.request;
}
public boolean received() {
return this.getReceived() != null;
}
@XmlElement(name = AckReceived.NAME)
public AckReceived getReceived() {
return this.received;
}
public boolean history() {
return this.getHistory() != null;
}
public History getHistory() {
return this.history;
}
/**
* 是否同时存在Received/Request(冲突)
*
* @return
*/
public boolean noneConflict() {
return !this.received() || !this.request();
}
/**
* 是否同时存在Received/Body且存在Received.id
*
* @return
*/
public boolean validReceived() {
return this.received() ? (this.getBody() == null && this.getReceived().valid()) : true;
}
public boolean content() {
return this.body != null && this.body.content();
}
@Override
public void set(String localName, Object ob) {
switch (localName) {
case XData.NAME:
this.x(ob);
return;
case Body.NAME:
this.body(Body.class.cast(ob));
return;
case Delay.NAME:
this.delay(Delay.class.cast(ob));
return;
case Thread.NAME:
this.thread(Thread.class.cast(ob));
return;
case Subject.NAME:
this.subject(Subject.class.cast(ob));
return;
case History.NAME:
this.history(History.class.cast(ob));
return;
case AckRequest.NAME:
this.request(AckRequest.class.cast(ob));
return;
case AckReceived.NAME:
this.received(AckReceived.class.cast(ob));
return;
}
}
}