private void createRobotServerMappingFile(List<Element> msgElements, String module)
      throws Exception {
    List<MessageObject> toGSMsgs = new ArrayList<MessageObject>();

    for (Iterator i = msgElements.iterator(); i.hasNext(); ) {
      Element message = (Element) i.next();
      MessageObject msg = new MessageObject();
      String msgType = message.getAttributeValue("type");
      msg.setType(msgType);
      msg.setClassName(GeneratorHelper.generateServerClassName(msgType));
      String msgTypePrefix = msgType.substring(1, 2);
      toGSMsgs.add(msg);
    }
    if (toGSMsgs.size() == 0) {
      return;
    }
    VelocityContext context = new VelocityContext();
    context.put("module", module);
    String mappingClassName = StringUtils.upperCaseFirstCharOnly(module) + "MsgMappingProvider";
    context.put("classname", mappingClassName);
    if (toGSMsgs.size() > 0) {
      context.put("msgs", toGSMsgs);
      String outputFile = robotRootPath + "msg" + File.separator + mappingClassName + ".java";
      GeneratorHelper.generate(context, robotMappingTemplate_game, outputFile);
    }
  }
 /**
  * 替换宏
  *
  * @param element
  * @param macroId
  * @return 仅当成功的进行宏替换后返回真
  */
 private boolean doReplaceMacros(Element element, String macroId) {
   if (!StringUtils.isEmpty(macroId)) {
     if (!macros.containsKey(macroId)) {
       logger.error("消息配置错误,不存在这样的宏定义:" + macroId);
       return false;
     }
     // 防止子macro被重复替换
     if (element.getChildren().size() > 0) {
       return false;
     }
     Element macro = macros.get(macroId);
     Element macroClone = (Element) macro.clone();
     element.addContent(macroClone.removeContent());
     return true;
   }
   return false;
 }
  /**
   * @param field
   * @param subFieldElements
   */
  private void setSubFields(FieldObject field, List<Element> subFieldElements) {
    List<FieldObject> subFields = new ArrayList<FieldObject>();
    fields.put(field.getType(), subFields);
    for (Element subElement : subFieldElements) {
      FieldObject subField = new FieldObject();
      subField.setType(subElement.getAttributeValue("type"));
      subField.setClientType(subElement.getAttributeValue("clientType"));
      if (StringUtils.isEmpty(subField.getClientType())) {
        subField.setClientType(GeneratorHelper.getClientClassName(subField.getType()) + "Data");
      }
      subField.setSmallName(subElement.getAttributeValue("name"));
      subField.setComment(subElement.getAttributeValue("comment"));
      if (subElement.getAttributeValue("list") != null) {
        subField.setList(subElement.getAttributeValue("list").equals("true") ? true : false);
        field.setHasListField(true);
      }
      subFields.add(subField);
      List<Element> subsubFieldElements = subElement.getChildren("field", NAME_SPACE);
      if (subsubFieldElements.size() > 0) {
        this.setSubFields(subField, subsubFieldElements);
      }

      // 如果不是系统定义的类型则说明是子消息
      if (!new ArrayListWrapper(sysTypes).contains(subField.getType())) {
        subField.setIsNewType(true);
        if (subField.getType().indexOf("_") > 0) {
          subField.setType(GeneratorHelper.generateServerClassName(subField.getType()));
        }
      }
    }
    field.setSubFields(subFields);
    // 如果配置了子节点,而且类型中不存在包名,则说明是新定义的类型
    if (field.getType().indexOf(".") == -1) {
      field.setNeedCreateType(true);
    }
  }
  /**
   * 设置消息对象的字段
   *
   * @param msgObj
   * @param msgElement
   */
  private void setMsgObjFields(
      MessageObject msgObj, List fElements, boolean isClient, boolean isCppClient) {
    for (Iterator j = fElements.iterator(); j.hasNext(); ) {
      Element fElement = (Element) j.next();
      FieldObject field = new FieldObject();
      field.setType(fElement.getAttributeValue("type"));
      field.setClientType(fElement.getAttributeValue("clientType"));
      if (StringUtils.isEmpty(field.getClientType())) {
        field.setClientType(GeneratorHelper.getClientClassName(field.getType()) + "Data");
      }
      field.setSmallName(fElement.getAttributeValue("name"));
      field.setComment(fElement.getAttributeValue("comment"));

      if (fElement.getAttribute("defaultValue") != null) {
        String defaultValue = fElement.getAttributeValue("defaultValue");
        if (StringUtils.isEmpty(defaultValue)) {
          if (!TYPE_STRING.equals(field.getType())) {
            defaultValue = "0";
          } else {
            defaultValue = "";
          }
        }
        if (TYPE_STRING.equals(field.getType())) {
          defaultValue = "\"" + defaultValue + "\"";
        }
        field.setDefaultValue("=" + defaultValue);
      } else {
        field.setDefaultValue("");
      }

      List<Element> subFieldElements = fElement.getChildren("field", NAME_SPACE);
      if (fElement.getAttributeValue("bytes") != null) {
        field.setBytes(fElement.getAttributeValue("bytes").equals("true") ? true : false);
      }
      if (fElement.getAttributeValue("list") != null) {
        field.setList(fElement.getAttributeValue("list").equals("true") ? true : false);
        msgObj.setHasListField(true);
      }

      boolean isSubMsg = "true".equalsIgnoreCase(fElement.getAttributeValue("subMsg"));
      field.setSubMsg(isSubMsg);
      if (isSubMsg) {
        field.setSubMsgType(GeneratorHelper.generateServerClassName(field.getType()));
        msgObj.setListMsg(true);
        if (isCppClient) {
          field.setList(true);
          msgObj.setHasListField(true);
          field.setType("_LZOBEX_" + field.getType());
        }
      }

      // 如果不是系统定义的类型则说明是子消息
      if (!new ArrayListWrapper(sysTypes).contains(field.getType())) {
        if (!isCppClient || !field.isSubMsg()) {
          field.setIsNewType(true);
          if (!isClient && field.getType().indexOf("_") > 0) {
            field.setType(GeneratorHelper.generateServerClassName(field.getType()));
          }
        }
      }

      if (subFieldElements.size() > 0) {
        this.setSubFields(field, subFieldElements);
      } else {
        if (isClient && field.getIsNewType()) { // 客户端生成消息的时候要为其补全
          field.setSubFields(fields.get(field.getType()));
        }
        if (!isClient && field.getList() && field.getIsNewType()) {
          String type = field.getType();
          field.setSubFields(msgs.get(type).getFields());
        }
      }
      if (field.isSubMsg() && !isCppClient) {
        msgObj.addSubMsg(field);
      } else {
        msgObj.addField(field);
      }
    }
  }
  /**
   * 生成客户端文件,每个模块一个文件
   *
   * @param msgElements
   * @throws Exception
   */
  private void createClientFile(
      List<Element> msgElements, String module, List<Element> contantElements) throws Exception {

    List<MessageObject> cgMsgs = new ArrayList<MessageObject>();
    List<MessageObject> gcMsgs = new ArrayList<MessageObject>();
    List<MessageObject> allClientMsgs = new ArrayList<MessageObject>();
    for (Iterator i = msgElements.iterator(); i.hasNext(); ) {
      Element mElement = (Element) i.next();
      MessageObject msgObj = new MessageObject();
      String msgType = mElement.getAttributeValue("type");
      fields.put(msgType, msgObj.getFields());
      msgObj.setType(msgType);
      msgObj.setClassName(GeneratorHelper.generateServerClassName(msgType));
      msgObj.setModule(mElement.getAttributeValue("module"));
      msgObj.setComment(mElement.getAttributeValue("comment"));
      msgObj.setHandleMethodName(GeneratorHelper.generateHandleMethodName(msgType));

      List fElements = mElement.getChildren("field", NAME_SPACE);
      this.setMsgObjFields(msgObj, fElements, true, false);
      if (msgType.substring(0, 2).equalsIgnoreCase("cg")) {
        cgMsgs.add(msgObj);
      } else if (msgType.substring(0, 2).equalsIgnoreCase("gc")) {
        gcMsgs.add(msgObj);
      }
      if (msgType.contains("c") || msgType.contains("C")) {
        allClientMsgs.add(msgObj);
      }
    }

    this.createClientModel(allClientMsgs, module);

    List<ConstantObject> contants = new ArrayList<ConstantObject>();
    for (Iterator i = contantElements.iterator(); i.hasNext(); ) {
      Element constantElement = (Element) i.next();
      String constantName = constantElement.getAttributeValue("name");
      String constantDesc = constantElement.getValue();
      ConstantObject constantObj =
          new ConstantObject(
              constantName,
              constantDesc
                  .replaceAll(File.separator + "n", "")
                  .replaceAll(File.separator + "r", "")
                  .trim());
      contants.add(constantObj);
    }

    VelocityContext context = new VelocityContext();
    context.put("module", StringUtils.upperCaseFirstCharOnly(module));
    context.put("modulename", module);
    for (String templateFileName : clientMsgTemplates) {
      String outputFileNameSuffix = null;
      String templatePrefix = templateFileName.substring(0, 2);
      if (templatePrefix.equals("gc")) {
        if (gcMsgs.size() == 0) {
          continue;
        }
        context.put("msgs", gcMsgs);
        outputFileNameSuffix = "GCMessage.as";
      } else if (templatePrefix.equals("cg")) {
        if (cgMsgs.size() == 0) {
          continue;
        }
        context.put("msgs", cgMsgs);
        outputFileNameSuffix = "CGMessage.as";
      }
      context.put("constants", contants);
      String outputFilePath;
      if (replaceDirectly) {
        outputFilePath =
            messagePath + StringUtils.upperCaseFirstCharOnly(module) + outputFileNameSuffix;
      } else {
        outputFilePath =
            clientRootPath
                + File.separator
                + module
                + File.separator
                + "message"
                + File.separator
                + StringUtils.upperCaseFirstCharOnly(module)
                + outputFileNameSuffix;
      }
      GeneratorHelper.generate(context, templateFileName, outputFilePath);
    }
  }