您的位置:首页 > 运维架构

openfire二次开发:使用Annotation注解VO转换xml文档

2013-06-20 16:09 495 查看
IQElementMapping是一个注解类,用于映射实体类与xml对象

/**
* openfire_src
*/
package com.kingray.openfire.plugin.packet;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* IQ映射注解,用于注解实体类的字段,帮助转换器转换为xml对象
* @author KRXiongYingqi
* @version 2013-6-17 上午10:44:44
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface IQElementMapping {
public String value();
}


VO接口,所有实体类的超类

package com.kingray.openfire.plugin.vo;

import java.io.Serializable;
/**
* VO类,所有实体类的超类
* @author KRXiongYingqi
* @version 2013-6-20 下午4:02:49
*/
public interface VO extends Serializable{

}


消息实体,使用IQElementMapping注解

package com.kingray.openfire.plugin.vo;

import java.util.Date;

import com.kingray.openfire.plugin.packet.IQElementMapping;
import com.xiongyingqi.util.DateHelper;

/**
* 消息实体,用于存储传递时用到的查询条件或返回结果
* @author KRXiongYingqi
* @version 2013-6-20 下午2:14:47
*/
@IQElementMapping("message")
public class MessageVO implements VO {
@IQElementMapping("messageId")
private long messageId;

@IQElementMapping("sendMessageId")
private String sendMessageId;

@IQElementMapping("messageFrom")
private String messageFrom;

@IQElementMapping("messageTo")
private String messageTo;

@IQElementMapping("messageSubject")
private String messageSubject;

@IQElementMapping("messageBody")
private String messageBody;

@IQElementMapping("messageDateTime")
private Date messageDateTime;

@IQElementMapping("messageDateTimeStr")
private String messageDateTimeStr;

@IQElementMapping("messageType")
private String messageType;

public MessageVO(){
}
public MessageVO(long messageId, String sendMessageId, String messageFrom, String messageTo, String messageBody){
this.messageId = messageId;
this.sendMessageId = sendMessageId;
this.messageFrom = messageFrom;
this.messageTo = messageTo;
this.messageBody = messageBody;
}
/**
* @return the messageType
*/
public String getMessageType() {
return messageType;
}
/**
* @param messageType the messageType to set
*/
public void setMessageType(String messageType) {
this.messageType = messageType;
}
/**
* @return the messageSubject
*/
public String getMessageSubject() {
return messageSubject;
}
/**
* @param messageSubject the messageSubject to set
*/
public void setMessageSubject(String messageSubject) {
this.messageSubject = messageSubject;
}
/**
* @return the messageId
*/
public long getMessageId() {
return messageId;
}
/**
* @param messageId the messageId to set
*/
public void setMessageId(long messageId) {
this.messageId = messageId;
}
/**
* @return the sendMessageId
*/
public String getSendMessageId() {
return sendMessageId;
}
/**
* @param sendMessageId the sendMessageId to set
*/
public void setSendMessageId(String sendMessageId) {
this.sendMessageId = sendMessageId;
}
/**
* @return the messageFrom
*/
public String getMessageFrom() {
return messageFrom;
}
/**
* @param messageFrom the messageFrom to set
*/
public void setMessageFrom(String messageFrom) {
if(messageFrom == null) messageFrom = "";
this.messageFrom = messageFrom;
}
/**
* @return the messageTo
*/
public String getMessageTo() {
return messageTo;
}
/**
* @param messageTo the messageTo to set
*/
public void setMessageTo(String messageTo) {
if(messageTo == null) messageTo = "";
this.messageTo = messageTo;
}
/**
* @return the messageBody
*/
public String getMessageBody() {
return messageBody;
}
/**
* @param messageBody the messageBody to set
*/
public void setMessageBody(String messageBody) {
this.messageBody = messageBody;
}
/**
* @return the messageDateTime
*/
public Date getMessageDateTime() {
return messageDateTime;
}
/**
* @param messageDateTime the messageDateTime to set
*/
public void setMessageDateTime(Date messageDateTime) {
this.messageDateTimeStr = DateHelper.FORMATTER_LONG.format(messageDateTime);
this.messageDateTime = messageDateTime;
}
/**
* @return the messageDateTimeStr
*/
public String getMessageDateTimeStr() {
return messageDateTimeStr;
}
/**
* @param messageDateTimeStr the messageDateTimeStr to set
*/
public void setMessageDateTimeStr(String messageDateTimeStr) {
this.messageDateTime = DateHelper.strToDateLong(messageDateTimeStr);
this.messageDateTimeStr = messageDateTimeStr;
}
@Override
public String toString() {
return this.getClass() + "@" + hashCode() + ": messageId: " + messageId + ", sendMessageId: "
+ sendMessageId + ", messageFrom: " + messageFrom + ", messageTo: " + messageTo + ", messageBody: "
+ messageBody + ", messageDateTime: " + messageDateTime;
}
}

xml转换工具,使用反射机制

/**
* openfire_src
*/
package com.xiongyingqi.convert;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;

import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.kingray.openfire.plugin.packet.KingrayNameSpace;
import com.kingray.openfire.plugin.vo.VO;
import com.xiongyingqi.util.StringHelper;

/**
* Xml转换工具
* @author KRXiongYingqi
* @version 2013-6-17 下午4:44:03
*/
public class XmlConvert {
private Class annotationClass;

public XmlConvert(Class annotationClass){
this.annotationClass = annotationClass;
}

/**
* 由Collection<? extends VO>转换为xml,被转换的类必须由有注解类注解
* <br>2013-6-17 下午4:44:45
* @param collection 消息集合
* @return org.dom4j.Element
*/
public Element convertVOs(Collection<? extends VO> collection){
Element element = DocumentHelper.createElement(KingrayNameSpace.QUERY_MESSAGE.getKey());
for (Iterator iterator = collection.iterator(); iterator.hasNext();) { // 遍历集合
Object instance =  iterator.next();
Class instanceClass = instance.getClass();

String elementName = null;
if(instanceClass.isAnnotationPresent(annotationClass)){ // 判断VO类是否包含了annotationClass的注解
Annotation annotation = instanceClass.getAnnotation(annotationClass); // 获取annotationClass的注解
Method[] methods = annotationClass.getMethods(); // 获取annotationClass的所有方法
if(methods.length > 1){ // 如果有多个注解
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
String methodName = method.getName(); // 注解方法的方法名

if("value".equals(methodName)){ // 是否为value方法
try {
elementName = (String) method.invoke(annotation);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
break;
}
}
} else if(methods.length == 1){
Method method = methods[0];
String methodName = method.getName(); // 注解方法的方法名

if("value".equals(methodName)){ // 是否为value方法
try {
elementName = (String) method.invoke(annotation);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}

}
if(StringHelper.nullOrEmpty(elementName)){
elementName = instance.getClass().getSimpleName();
}
Element messageElement = DocumentHelper.createElement(elementName); // 创建节点

//			Class clazz = IQElementMapping.class;
Field[] fields = instance.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) { // 遍历每个字段
Field field = fields[i];
if(field.isAnnotationPresent(annotationClass)){ // 检测是否为IQElementMapping的注解类型
Annotation annotation = field.getAnnotation(annotationClass);
Method[] methods = annotationClass.getDeclaredMethods(); // 获取注解类的所有方法
for (int j = 0; j < methods.length; j++) {
Method annoutationMethod = methods[j];
String fieldName = null;
try {
fieldName = annoutationMethod.invoke(annotation) + ""; // 获取注解方法的返回值
} catch (IllegalArgumentException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (InvocationTargetException e1) {
e1.printStackTrace();
}
//						annotation.value();
String fieldValue = null; // 被注解的字段的值
try {
String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); // 使用bean的方法
Method method = instance.getClass().getDeclaredMethod(methodName);
Object returnObject = method.invoke(instance);
if(returnObject != null){
fieldValue = returnObject + "";
}
//						fieldValue = (String) field.get(messageVO);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
if(StringHelper.notNullAndNotEmpty(fieldValue)){
messageElement.addAttribute(fieldName, fieldValue);  // 为每个字段设置属性
}
}
}
}
element.add(messageElement);
}
return element;
}
}


IQ处理器,用于处理客户端发送的查询IQ

package com.kingray.openfire.plugin.handler;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.jivesoftware.openfire.IQHandlerInfo;
import org.jivesoftware.openfire.IQRouter;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.disco.ServerFeaturesProvider;
import org.jivesoftware.openfire.handler.IQHandler;
import org.jivesoftware.openfire.session.ClientSession;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;

import com.kingray.openfire.plugin.dao.MessageDAO;
import com.kingray.openfire.plugin.dao.impl.MessageDAOImpl;
import com.kingray.openfire.plugin.packet.IQElementMapping;
import com.kingray.openfire.plugin.packet.KingrayNameSpace;
import com.kingray.openfire.plugin.packet.MessageHistoryIQ;
import com.kingray.openfire.plugin.vo.MessageVO;
import com.xiongyingqi.convert.XmlConvert;
import com.xiongyingqi.util.CalendarHelper;
import com.xiongyingqi.util.DateHelper;
import com.xiongyingqi.util.StringHelper;

/**
* 服务类,用于处理客户端的数据查询等请求
* @author XiongYingqi
*
*/
public class KingrayMessageHistoryIQHandler extends IQHandler implements ServerFeaturesProvider {
private static final KingrayNameSpace QUERY_MESSAGE = KingrayNameSpace.QUERY_MESSAGE; // 命名空间
private MessageDAO messageDAO;
private XmlConvert convert;

private IQHandlerInfo info;

private String serverString;

public KingrayMessageHistoryIQHandler() {
super(QUERY_MESSAGE.getKey()); // 取一个处理器名
messageDAO = new MessageDAOImpl();
convert = new XmlConvert(IQElementMapping.class);
info = new IQHandlerInfo(QUERY_MESSAGE.getKey(), QUERY_MESSAGE.getValue());

XMPPServer server = XMPPServer.getInstance();
serverString = server.getServerInfo().getXMPPDomain();

// 注册IQ处理服务
IQRouter iqRouter = server.getIQRouter();
iqRouter.addHandler(this);

//		server.getServerFeaturesProviders().add(this);
//		server.getIQDiscoInfoHandler().addServerFeature(QUERY_MESSAGE.getValue());

}

@Override
public IQ handleIQ(IQ packet) throws UnauthorizedException {
System.out.println("packet.toXML() =========== " + packet.toXML());
IQ response = handleMessageHistory(packet);

response.setType(IQ.Type.result);
response.setFrom(serverString);
JID fromJid = packet.getFrom();
ClientSession session = XMPPServer.getInstance().getSessionManager().getSession(fromJid);
if(session == null){ //
response.setChildElement(packet.getChildElement().createCopy());
response.setError(PacketError.Condition.not_authorized);
}
//		session.process(response);
//		deliverer.deliver(response);

System.out.println(this.getClass() + " handleIQ ====== " + response.toXML());
//		response = null;
return response;
}

/**
* 处理消息记录
* <br>2013-6-18 上午9:49:27
* @param packet
* @return
*/
public IQ handleMessageHistory(IQ packet){
IQ response = IQ.createResultIQ(packet);

String userName = packet.getFrom().getNode();

// 读取根节点数据
Element element = packet.getChildElement();
String relationUserName = element.attributeValue("relationUserName");
String actionType = element.attributeValue("actionType");
String messageDateTimeStr = element.attributeValue("messageDateTime");

Date messageDateTime = null;
if(StringHelper.notNullAndNotEmpty(messageDateTimeStr)){
try {
messageDateTime = DateHelper.strToDate(messageDateTimeStr);
} catch (Exception e) {
}
}

//读取<message节点数据>
Collection<Long> messageIds = new HashSet<Long>();
Collection<String> sendMessageIds = new HashSet<String>();

List messageElements = element.elements();
for (Iterator iterator = messageElements.iterator(); iterator.hasNext();) {
Element messageElement = (Element) iterator.next();
String messageIdStr = messageElement.attributeValue("messageId"); // 优先读取messageId
if(StringHelper.notNullAndNotEmpty(messageIdStr)){
Long messageId = Long.parseLong(messageIdStr);
messageIds.add(messageId);
} else { // 如果不存在messageId属性,则读取sendMessageId
String sendMessageId = messageElement.attributeValue("sendMessageId");
if(StringHelper.notNullAndNotEmpty(sendMessageId)){
sendMessageIds.add(sendMessageId);
}
}
}

if(!StringHelper.notNullAndNotEmpty(actionType)){ // 判断是否指定actionType,如果没有指定,则默认使用QUERY_COUNT
actionType = MessageHistoryIQ.MessageHistoryActionType.QUERY_COUNT.toString();
}
Element resultElement = null;

if(actionType.equals(MessageHistoryIQ.MessageHistoryActionType.QUERY_COUNT.toString())){ // 查询条数
int messageHistoryCount = messageDAO.getMessageHistoryCountByUserName(userName, relationUserName, messageDateTime);
resultElement = handleMessageHistoryCountResponseIQ(response, messageHistoryCount, relationUserName, messageDateTime);
} else if(actionType.equals(MessageHistoryIQ.MessageHistoryActionType.QUERY_SUMMARY.toString())){ // 查询预览
Collection<MessageVO> messageVOs = messageDAO.getMessageHistorySummaryByUserName(userName, relationUserName, messageDateTime);
resultElement = convert.convertVOs(messageVOs); // 将获取的数据转换为xml
} else if(actionType.equals(MessageHistoryIQ.MessageHistoryActionType.QUERY_DETAIL.toString())){ // 查询详细消息
Collection<MessageVO> messageVOs = null;
// 检查查询条件,如果查询条件不足,那么就返回错误
if(messageIds != null && messageIds.size() > 0){
messageVOs = messageDAO.getMessageHistoryDetailByMessageIds(messageIds);
} else if(sendMessageIds != null && sendMessageIds.size() > 0){
messageVOs = messageDAO.getMessageHistoryDetailBySendMessageIds(sendMessageIds);
} else if(StringHelper.notNullAndNotEmpty(userName)){
messageVOs = messageDAO.getMessageHistoryDetailByUserName(userName, relationUserName, messageDateTime);
} else { // 查询条件不足,返回错误
response.setChildElement(packet.getChildElement().createCopy());
response.setError(PacketError.Condition.bad_request);
return response;
}

if(messageVOs != null){
resultElement = convert.convertVOs(messageVOs); // 将获取的数据转换为xml
}
}
System.out.println("resultElement ======== " + resultElement);
resultElement.addAttribute("actionType", actionType); // 加入actionType
resultElement.addNamespace("", QUERY_MESSAGE.getValue()); // 加入命名空间
response.setChildElement(resultElement);

return response;
}
/**
* 返回总消息数的IQ
* <br>2013-6-17 下午3:26:22
* @param packet
* @param messageCount
* @param relationUserName
* @param messageDateTime
* @return
*/
public Element handleMessageHistoryCountResponseIQ(IQ packet, int messageHistoryCount, String relationUserName, Date messageDateTime){
Element element = DocumentHelper.createElement(QUERY_MESSAGE.getKey());
//		Element messageHistoryCountElement = DocumentHelper.createElement("messageHistoryCount");
//		messageHistoryCountElement.setData(messageHistoryCount);
//		element.add(messageHistoryCountElement);
element.addAttribute("messageHistoryCount", messageHistoryCount + "");
if(StringHelper.notNullAndNotEmpty(relationUserName)){
element.addAttribute("relationUserName", relationUserName);
}
if(messageDateTime != null){
element.addAttribute("messageDateTime", DateHelper.dateToStr(messageDateTime));
}
element.addNamespace("", QUERY_MESSAGE.getValue()); // 加入命名空间
//		packet.setChildElement(element);
return element;
}

/**
* 必须实现该方法,否则openfire将无法实例化本处理器
*/
@Override
public IQHandlerInfo getInfo() {
return info;
}

/**
* <br>2013-6-19 下午5:56:05
* @see org.jivesoftware.openfire.disco.ServerFeaturesProvider#getFeatures()
*/
@Override
public Iterator<String> getFeatures() {
ArrayList<String> features = new ArrayList<String>();
features.add(QUERY_MESSAGE.getValue());
return features.iterator();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: