package com.sissi.context.impl;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBObject;
import com.sissi.config.Dictionary;
import com.sissi.config.MongoConfig;
import com.sissi.config.impl.MongoUtils;
import com.sissi.context.JID;
import com.sissi.context.JIDContext;
import com.sissi.context.Status;
import com.sissi.context.StatusBuilder;
import com.sissi.context.StatusClauses;
import com.sissi.field.impl.BeanField;
import com.sissi.ucenter.vcard.VCardContext;
/**
* 索引策略:{"index":-1,"jid":1,"resource":1}
*
* @author kim 2013-11-21
*/
public class MongoStatusBuilder implements StatusBuilder {
/**
* 过滤策略,{"avator":1,"show":1,"status":1,"type":1,"priority":1}
*/
private final DBObject filter = BasicDBObjectBuilder.start().add(StatusClauses.KEY_AVATOR, 1).add(StatusClauses.KEY_SHOW, 1).add(StatusClauses.KEY_STATUS, 1).add(StatusClauses.KEY_TYPE, 1).add(StatusClauses.KEY_PRIORITY, 1).get();
private final VCardContext vcardContext;
private final MongoConfig config;
public MongoStatusBuilder(VCardContext vcardContext, MongoConfig addressing) {
this(vcardContext, addressing, true);
}
public MongoStatusBuilder(VCardContext vcardContext, MongoConfig addressing, boolean reset) {
super();
this.vcardContext = vcardContext;
this.config = reset ? addressing.reset() : addressing;
}
@Override
public Status build(JIDContext context) {
return new MongoStatus(context);
}
/**
* 清除出席状态</p>{"index":Xxx,"jid":Xxx,"resource":Xxx}
*
* @param context
* @return
*/
private MongoStatusBuilder reset(JIDContext context) {
this.config.collection().remove(this.buildQuery(context));
return this;
}
/**
* 全量更新</p>{"set":{"type":Xxx,"show":Xxx,"status":Xxx,"avator":Xxx,"priority":Xxx}}
*
* @param context
* @param type
* @param show
* @param status
* @param avator
* @return
*/
private MongoStatusBuilder set(JIDContext context, String type, String show, String status, String avator) {
if (MongoUtils.success(this.config.collection().update(this.buildQuery(context), BasicDBObjectBuilder.start().add("$set", BasicDBObjectBuilder.start().add(StatusClauses.KEY_TYPE, type).add(StatusClauses.KEY_SHOW, show).add(StatusClauses.KEY_STATUS, status).add(StatusClauses.KEY_AVATOR, avator).add(Dictionary.FIELD_PRIORITY, context.priority()).get()).get()))) {
if (avator != null) {
this.vcardContext.push(context.jid(), new BeanField<String>().name(VCardContext.FIELD_AVATOR).value(avator));
}
}
return this;
}
private StatusClauses get(JIDContext context) {
return new MongoClauses(context.jid(), this.config.collection().findOne(this.buildQuery(context), this.filter));
}
/**
* {"index":Xxx,"jid":Xxx,"resource":Xxx}
*
* @param context
* @return
*/
private DBObject buildQuery(JIDContext context) {
return BasicDBObjectBuilder.start().add(Dictionary.FIELD_INDEX, context.index()).add(Dictionary.FIELD_JID, context.jid().asStringWithBare()).add(Dictionary.FIELD_RESOURCE, context.jid().resource()).get();
}
private class MongoStatus implements Status {
private final JIDContext context;
public MongoStatus(JIDContext context) {
super();
this.context = context;
}
public MongoStatus clear() {
MongoStatusBuilder.this.reset(this.context);
return this;
}
public Status clauses(StatusClauses clauses) {
MongoStatusBuilder.this.set(this.context, clauses.find(StatusClauses.KEY_TYPE), clauses.find(StatusClauses.KEY_SHOW), clauses.find(StatusClauses.KEY_STATUS), clauses.find(StatusClauses.KEY_AVATOR));
return this;
}
@Override
public StatusClauses clauses() {
return MongoStatusBuilder.this.get(this.context);
}
}
private class MongoClauses implements StatusClauses {
private final DBObject status;
private final JID jid;
public MongoClauses(JID jid, DBObject status) {
super();
this.jid = jid;
this.status = status;
}
@Override
public String find(String key) {
switch (key) {
case StatusClauses.KEY_AVATOR: {
String avator = MongoUtils.asString(this.status, key);
return avator != null ? avator : MongoStatusBuilder.this.vcardContext.pull(this.jid, VCardContext.FIELD_AVATOR, avator).getValue();
}
default:
return MongoUtils.asString(this.status, key);
}
}
}
}