package com.owent.xresloader.data.dst; import com.owent.xresloader.ProgramOptions; import com.owent.xresloader.data.err.ConvException; import com.owent.xresloader.scheme.SchemeConf; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; import java.io.ByteArrayOutputStream; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by owentou on 2014/10/10. */ public class DataDstXml extends DataDstJava { @Override public boolean init() { return true; } /** * @return 协议处理器名字 */ public String name() { return "xml"; } @Override public final byte[] build(DataDstImpl compiler) throws ConvException { // pretty print OutputFormat of = null; if (ProgramOptions.getInstance().prettyIndent <= 0) { of = OutputFormat.createCompactFormat(); } else { of = OutputFormat.createPrettyPrint(); of.setIndentSize(ProgramOptions.getInstance().prettyIndent); } // build data DataDstObject data_obj = build_data(compiler); // build xml tree Document doc = DocumentHelper.createDocument(); String encoding = SchemeConf.getInstance().getKey().getEncoding(); if (null != encoding && false == encoding.isEmpty()) { doc.setXMLEncoding(encoding); of.setEncoding(encoding); } doc.setRootElement(DocumentHelper.createElement(ProgramOptions.getInstance().xmlRootName)); doc.getRootElement().addComment("this file is generated by xresloader, please don't edit it."); Element header = DocumentHelper.createElement("header"); Element body = DocumentHelper.createElement("body"); writeData(header, data_obj.header, header.getName()); // body for(Map.Entry<String, List<Object> > item: data_obj.body.entrySet()) { for(Object obj: item.getValue()) { Element xml_item = DocumentHelper.createElement(item.getKey()); writeData(xml_item, obj, item.getKey()); body.add(xml_item); } } writeData(body, data_obj.body, body.getName()); doc.getRootElement().add(header); doc.getRootElement().add(body); try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); XMLWriter writer = new XMLWriter(bos, of); writer.write(doc); return bos.toByteArray(); } catch(Exception e) { ProgramOptions.getLoger().error("write xml failed, %s", e.getMessage()); return null; } } @Override public final DataDstWriterNode compile() { ProgramOptions.getLoger().error("lua can not be protocol description."); return null; } private void writeData(Element sb, Object data, String wrapper_name) { // null if (null == data) { return; } // 数字 // 枚举值已被转为Java Long,会在这里执行 if (data instanceof Number) { sb.addText(data.toString()); return; } // 布尔 if (data instanceof Boolean) { sb.addText(((Boolean) data) ? "true" : "false"); return; } // 字符串&二进制 if (data instanceof String) { sb.addText(data.toString()); return; } // 列表 if (data instanceof List) { List<Object> ls = (List<Object>)data; int index = 0; for(Object obj: ls) { Element list_ele = DocumentHelper.createElement(wrapper_name); Attribute index_attr = DocumentHelper.createAttribute(list_ele, "for", String.valueOf(index)); list_ele.add(index_attr); writeData(list_ele, obj, wrapper_name); sb.add(list_ele); ++ index; } return; } // Hashmap if (data instanceof Map) { Map<String, Object> mp = (Map<String, Object>)data; for(Map.Entry<String, Object> item: mp.entrySet()) { // 数据会多一层,这里去除 if (item.getValue() instanceof List) { writeData(sb, item.getValue(), item.getKey()); } else { Element xml_item = DocumentHelper.createElement(item.getKey()); writeData(xml_item, item.getValue(), item.getKey()); sb.add(xml_item); } } return; } ProgramOptions.getLoger().error("%s not support.", data.toString()); } /** * 转储常量数据 * @return 常量数据,不支持的时候返回空 */ public final byte[] dumpConst(HashMap<String, Object> data) { // pretty print OutputFormat of = null; if (ProgramOptions.getInstance().prettyIndent <= 0) { of= OutputFormat.createCompactFormat(); } else { of = OutputFormat.createPrettyPrint(); of.setIndentSize(ProgramOptions.getInstance().prettyIndent); } // build xml tree Document doc = DocumentHelper.createDocument(); String encoding = SchemeConf.getInstance().getKey().getEncoding(); if (null != encoding && false == encoding.isEmpty()) { doc.setXMLEncoding(encoding); of.setEncoding(encoding); } doc.setRootElement(DocumentHelper.createElement(ProgramOptions.getInstance().xmlRootName)); doc.getRootElement().addComment("this file is generated by xresloader, please don't edit it."); writeData(doc.getRootElement(), data, ""); try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); XMLWriter writer = new XMLWriter(bos, of); writer.write(doc); return bos.toByteArray(); } catch(Exception e) { ProgramOptions.getLoger().error("write xml failed, %s", e.getMessage()); return null; } } }