def display(num=1): """ 展示错误统计结果 :param num: 对齐 """ result = json.dumps(ErrorUtil.error_dict, indent=num) logger.error(result) return result
def init(target): """ 解析excel文件,收集要处理的数据, 为target目标对象生成dto :param target: 目标对象有:openapi\pmbank\通用 """ protocol_file = CodeTemplate.java_template.get("protocol_file") if os.path.isfile(protocol_file): excel_data = xlrd.open_workbook(protocol_file) sheets = excel_data.sheets() sheet_names = excel_data.sheet_names() sheet_num = len(sheets) if 0 >= sheet_num: logger.error("data not found in excel") return index = 0 protocol_data = [] while index < sheet_num: dto_num = 0 need_import_module = [] sheet_origin_name = sheet_names[index].strip() # 从excel读到的sheet名称,为unicode格式, 需转换为utf-8编码 sheet_origin_name = sheet_origin_name.encode('utf-8') sheet_name = excel_conf.get("sheets_name_dict").get(sheet_origin_name) if sheet_name is None: index += 1 logger.warn("sheet_name=%s not in dict, no need to parse" % sheet_origin_name) continue content = { "sheet_name": sheet_name, "dto_elems": [], "need_import_module": [], } table = sheets[index] nrows = table.nrows # 加载excel描述规则 row_format = excel_conf.get("sheets_row_format") if row_format is None: logger.error("miss option sheets_row_format") return min_field_num = row_format.get("field_min_num") if min_field_num is None: logger.error("miss option field_min_num") return field_pos = excel_conf.get("sheets_field_position") if field_pos is None: logger.error("miss option sheets_field_position") return pos_id = field_pos.get("field_id") pos_name = field_pos.get("field_name") pos_comment = field_pos.get("field_comment") pos_type = field_pos.get("field_type") if pos_id is None or pos_name is None or pos_type is None: logger.error("miss field_id or field_name or field_type in sheets_field_position") return # 用于内嵌的文件 nest_dto_filename = "" nest_dto_fp = "" nest_dto_elems = [] nest_dto_import_module = [] lv2_nest_dto_filename = "" lv2_nest_dto_fp = "" lv2_nest_dto_elems = [] lv2_nest_dto_import_module = [] # 公共的解析逻辑,基于excel描述规则 for i in xrange(nrows): # 默认不需要生成嵌套的dto, 目前只支持2层嵌套 need_create_nest_dto = False lv2_need_create_nest_dto = False data = table.row_values(i) if len(data) < min_field_num: logger.warn("sheet_name=%s row=%s miss some cols, you need at least %s cols" % ( sheet_name, i, min_field_num)) continue # 字段位置id print type(data[pos_id]) dto_field_id = data[pos_id] print dto_field_id if data[pos_id] is None: logger.error("sheet_name=%s row=%s miss field_id" % (sheet_origin_name, i)) ErrorUtil.addInvalidFieldId(target, sheet_name, data[pos_name] if data[pos_name] is not None else "unknown") elif type(data[pos_id]) == int or str(data[pos_id]).strip().isdigit(): dto_field_id = int(data[pos_id]) elif type(data[pos_id]) == float: if CommonUtil.isFloat(dto_field_id): # 如果确实为浮点数, 则意味着需要生成嵌套的dto need_create_nest_dto = True else: tmp = str(data[pos_id]).strip() dot_count = tmp.count('.') if dot_count == 1: need_create_nest_dto = True elif dot_count == 2: need_create_nest_dto = True lv2_need_create_nest_dto = True else: print type(data[pos_id]) continue # 一层嵌套是否需要退出 if not need_create_nest_dto and not CommonUtil.is_empty(nest_dto_fp): nest_dto_content = { "sheet_name": nest_dto_filename, "dto_elems": nest_dto_elems, "need_import_module": nest_dto_import_module, } CodeGenerator.gen_code(nest_dto_content, target) # 二层嵌套是否需要退出 if not lv2_need_create_nest_dto and not CommonUtil.is_empty(lv2_nest_dto_fp): lv2_nest_dto_content = { "sheet_name": lv2_nest_dto_filename, "dto_elems": lv2_nest_dto_elems, "need_import_module": lv2_nest_dto_import_module, } CodeGenerator.gen_code(lv2_nest_dto_content, target) # 字段名校验 if CommonUtil.is_empty(data[pos_name]): logger.error("sheet_name=%s have empty field_name, please check" % sheet_origin_name) ErrorUtil.addEmptyFieldName(target); continue dto_field_name = str(data[pos_name]).strip() dto_field_type = str(CodeTemplate.java_template.get("default_field_type") if CommonUtil.is_empty( data[pos_type]) else data[pos_type]).strip() # 字段类型校验--预处理完还是没有, 则过滤该行 if CommonUtil.is_empty(dto_field_type): ErrorUtil.addInvalidFieldType(target, sheet_name, dto_field_name) continue # 特殊处理( pos = dto_field_type.find('(') if pos > 0: dto_field_type = dto_field_type[0:pos] # 字段类型二次校验 -- 检查以'('号开始的类型 if 0 == pos: ErrorUtil.addInvalidFieldType(target, sheet_name, dto_field_name) # 字段注释 dto_field_comment = str("" if data[pos_comment] is None else data[pos_comment]).strip() # 当读到字段id为1,且当前尚未生成过Dto时,需 # 1.更新sheet_name # 2.dto计数加1 # 当读到字段id为1,且已生成过dto时,需 # 1.将已有的content内容加入protocol_data中 # 2.初始化content if 1 == dto_field_id: if 0 == dto_num: content["sheet_name"] = sheet_name + CodeTemplate.java_template.get( "default_request_filename_postfix") dto_num += 1 CodeGenerator.setRequestPropertyStyle(target) else: content["need_import_module"] = need_import_module need_import_module = [] CodeGenerator.gen_code(content, target) content["sheet_name"] = sheet_name + CodeTemplate.java_template.get( "default_response_filename_postfix") content["dto_elems"] = [] content["need_import_module"] = [] CodeGenerator.setResponsePropertyStyle(target) # 是否包含list类型字段 tmp_type = dto_field_type.lower() if tmp_type in ["list", "array"]: if lv2_need_create_nest_dto and "list" not in lv2_nest_dto_import_module: lv2_nest_dto_import_module.append("list") elif need_create_nest_dto and "list" not in nest_dto_import_module: nest_dto_import_module.append("list") else: if "list" not in need_import_module: need_import_module.append("list") dir_path = CodeTemplate.java_template.get("default_file_path").get("output_" + target) % CodeGenerator.service_name if not os.path.exists(dir_path): os.makedirs(dir_path) # 为Array、List字段生成独立的dto文件 # 并使后续的小数点字段进入该dto内部 # 不支持嵌套array的情况, 所以这里只有为false时,才会生成dto, 否则前面生成的数据会被覆盖 if not need_create_nest_dto: nest_dto_filename = CamelTransformTool.trans_underline_field_to_camel_classname( dto_field_name) + "DTO" nest_dto_fp = open(dir_path + nest_dto_filename + ".java", "w+") nest_dto_elems = [] nest_dto_import_module = [] elif not lv2_need_create_nest_dto: lv2_nest_dto_filename = CamelTransformTool.trans_underline_field_to_camel_classname( dto_field_name) + "DTO" lv2_nest_dto_fp = open(dir_path + lv2_nest_dto_filename + ".java", "w+") lv2_nest_dto_elems = [] lv2_nest_dto_import_module = [] # 是否包含date类型 if tmp_type in ["t", "d", "date"]: if lv2_need_create_nest_dto and "date" not in lv2_nest_dto_import_module: lv2_nest_dto_import_module.append("date") elif need_create_nest_dto and "date" not in nest_dto_import_module: nest_dto_import_module.append("date") else: if "date" not in need_import_module: need_import_module.append("date") # 是否包含decimal类型 if tmp_type in ["b", "decimal", "bigdecimal"]: if lv2_need_create_nest_dto and "big_decimal" not in lv2_nest_dto_import_module: lv2_nest_dto_import_module.append("big_decimal") elif need_create_nest_dto and "big_decimal" not in nest_dto_import_module: nest_dto_import_module.append("big_decimal") else: if "big_decimal" not in need_import_module: need_import_module.append("big_decimal") if dto_field_name is None or dto_field_type is None: logger.error("dto_field_name or dto_field_type miss, please check you protocol file") continue dto_elem = { "name": dto_field_name, "type": dto_field_type, "comment": dto_field_comment, } # 如果是嵌套的,则进入嵌套文件DTO中 if lv2_need_create_nest_dto: lv2_nest_dto_elems.append(dto_elem) elif need_create_nest_dto: nest_dto_elems.append(dto_elem) else: content["dto_elems"].append(dto_elem) if dto_num > 0: content["need_import_module"] = need_import_module protocol_data.append(content) index += 1 return protocol_data else: logger.error("protocol_file=%s not exist" % protocol_file) print "protocol_file=%s not exist" % protocol_file return []
def gen_body(fp, sheet): """ 生成代码主体 :param sheet: :param fp: """ sheet_name = sheet.get("sheet_name") dto_elems = sheet.get("dto_elems") if dto_elems is not None and sheet_name is not None: classname = sheet_name CodeGenerator.class_define_begin(fp, classname) for elem in dto_elems: elem_type = TypeDict.type_dict.get(elem.get("type").lower()) if elem_type is None: logger.error("Unknown or miss field type, elem=%s" % str(elem)) continue elem_field_name = CamelTransformTool.trans_underline_field_to_camel_field(elem.get("name")) if elem_field_name is None: logger.error("miss field_name, elem=%s" % str(elem)) continue # 定义属性 elem_property_comment = elem.get("comment") CodeGenerator.property_comment(fp, elem_property_comment) # 在属性上添加注解, 默认的注解方式 if CodeTemplate.java_template.get("style_json_property") == Constant.json_property_style.get( "above_property"): CodeGenerator.json_property(fp, elem.get("name")) CodeGenerator.property_define(fp, elem_type, elem_field_name) for elem in dto_elems: elem_type = TypeDict.type_dict.get(elem.get("type").lower()) elem_field_name = CamelTransformTool.trans_underline_field_to_camel_field(elem.get("name")) elem_field_name_cap = CamelTransformTool.trans_underline_field_to_camel_classname(elem.get("name")) if elem_type is None or elem_field_name is None: continue # 定义set函数 elem_property_comment = elem.get("comment") CodeGenerator.function_comment(fp, elem_field_name, elem_property_comment) if CodeTemplate.java_template.get("style_json_property") == Constant.json_property_style.get( "above_function_set_upper_case"): CodeGenerator.json_property(fp, elem.get("name")) if CodeTemplate.java_template.get("style_json_property") == Constant.json_property_style.get( "above_function_set_lower_case"): CodeGenerator.json_property(fp, elem_field_name) CodeGenerator.json_serialize(fp) CodeGenerator.function_define_set(fp, elem_type, elem_field_name, elem_field_name_cap) # 定义get函数 CodeGenerator.function_comment(fp) if CodeTemplate.java_template.get("style_json_property") == Constant.json_property_style.get( "above_function_set_upper_case"): CodeGenerator.json_property(fp, elem_field_name) if CodeTemplate.java_template.get("style_json_property") == Constant.json_property_style.get( "above_function_set_lower_case"): CodeGenerator.json_property(fp, elem.get("name")) CodeGenerator.json_serialize(fp) CodeGenerator.function_define_get(fp, elem_type, elem_field_name, elem_field_name_cap) CodeGenerator.class_define_end(fp)
def init(target): """ 解析excel文件,收集要处理的数据, 为target目标对象生成dto :param target: 目标对象有:openapi\pmbank\通用 """ protocol_file = CodeTemplate.java_template.get("protocol_file") if os.path.isfile(protocol_file): excel_data = xlrd.open_workbook(protocol_file) sheets = excel_data.sheets() sheet_names = excel_data.sheet_names() sheet_num = len(sheets) if 0 >= sheet_num: logger.error("data not found in excel") return index = 0 protocol_data = [] while index < sheet_num: dto_num = 0 need_import_module = [] sheet_origin_name = sheet_names[index].strip() # 从excel读到的sheet名称,为unicode格式, 需转换为utf-8编码 sheet_origin_name = sheet_origin_name.encode('utf-8') sheet_name = excel_conf.get("sheets_name_dict").get( sheet_origin_name) if sheet_name is None: index += 1 logger.warn("sheet_name=%s not in dict, no need to parse" % sheet_origin_name) continue content = { "sheet_name": sheet_name, "dto_elems": [], "need_import_module": [], } table = sheets[index] nrows = table.nrows # 加载excel描述规则 row_format = excel_conf.get("sheets_row_format") if row_format is None: logger.error("miss option sheets_row_format") return min_field_num = row_format.get("field_min_num") if min_field_num is None: logger.error("miss option field_min_num") return field_pos = excel_conf.get("sheets_field_position") if field_pos is None: logger.error("miss option sheets_field_position") return pos_id = field_pos.get("field_id") pos_name = field_pos.get("field_name") pos_comment = field_pos.get("field_comment") pos_type = field_pos.get("field_type") if pos_id is None or pos_name is None or pos_type is None: logger.error( "miss field_id or field_name or field_type in sheets_field_position" ) return # 用于内嵌的文件 nest_dto_filename = "" nest_dto_fp = "" nest_dto_elems = [] nest_dto_import_module = [] lv2_nest_dto_filename = "" lv2_nest_dto_fp = "" lv2_nest_dto_elems = [] lv2_nest_dto_import_module = [] # 公共的解析逻辑,基于excel描述规则 for i in xrange(nrows): # 默认不需要生成嵌套的dto, 目前只支持2层嵌套 need_create_nest_dto = False lv2_need_create_nest_dto = False data = table.row_values(i) if len(data) < min_field_num: logger.warn( "sheet_name=%s row=%s miss some cols, you need at least %s cols" % (sheet_name, i, min_field_num)) continue # 字段位置id print type(data[pos_id]) dto_field_id = data[pos_id] print dto_field_id if data[pos_id] is None: logger.error("sheet_name=%s row=%s miss field_id" % (sheet_origin_name, i)) ErrorUtil.addInvalidFieldId( target, sheet_name, data[pos_name] if data[pos_name] is not None else "unknown") elif type(data[pos_id]) == int or str( data[pos_id]).strip().isdigit(): dto_field_id = int(data[pos_id]) elif type(data[pos_id]) == float: if CommonUtil.isFloat(dto_field_id): # 如果确实为浮点数, 则意味着需要生成嵌套的dto need_create_nest_dto = True else: tmp = str(data[pos_id]).strip() dot_count = tmp.count('.') if dot_count == 1: need_create_nest_dto = True elif dot_count == 2: need_create_nest_dto = True lv2_need_create_nest_dto = True else: print type(data[pos_id]) continue # 一层嵌套是否需要退出 if not need_create_nest_dto and not CommonUtil.is_empty( nest_dto_fp): nest_dto_content = { "sheet_name": nest_dto_filename, "dto_elems": nest_dto_elems, "need_import_module": nest_dto_import_module, } CodeGenerator.gen_code(nest_dto_content, target) # 二层嵌套是否需要退出 if not lv2_need_create_nest_dto and not CommonUtil.is_empty( lv2_nest_dto_fp): lv2_nest_dto_content = { "sheet_name": lv2_nest_dto_filename, "dto_elems": lv2_nest_dto_elems, "need_import_module": lv2_nest_dto_import_module, } CodeGenerator.gen_code(lv2_nest_dto_content, target) # 字段名校验 if CommonUtil.is_empty(data[pos_name]): logger.error( "sheet_name=%s have empty field_name, please check" % sheet_origin_name) ErrorUtil.addEmptyFieldName(target) continue dto_field_name = str(data[pos_name]).strip() dto_field_type = str( CodeTemplate.java_template.get("default_field_type" ) if CommonUtil. is_empty(data[pos_type]) else data[pos_type]).strip() # 字段类型校验--预处理完还是没有, 则过滤该行 if CommonUtil.is_empty(dto_field_type): ErrorUtil.addInvalidFieldType(target, sheet_name, dto_field_name) continue # 特殊处理( pos = dto_field_type.find('(') if pos > 0: dto_field_type = dto_field_type[0:pos] # 字段类型二次校验 -- 检查以'('号开始的类型 if 0 == pos: ErrorUtil.addInvalidFieldType(target, sheet_name, dto_field_name) # 字段注释 dto_field_comment = str("" if data[pos_comment] is None else data[pos_comment]).strip() # 当读到字段id为1,且当前尚未生成过Dto时,需 # 1.更新sheet_name # 2.dto计数加1 # 当读到字段id为1,且已生成过dto时,需 # 1.将已有的content内容加入protocol_data中 # 2.初始化content if 1 == dto_field_id: if 0 == dto_num: content[ "sheet_name"] = sheet_name + CodeTemplate.java_template.get( "default_request_filename_postfix") dto_num += 1 CodeGenerator.setRequestPropertyStyle(target) else: content["need_import_module"] = need_import_module need_import_module = [] CodeGenerator.gen_code(content, target) content[ "sheet_name"] = sheet_name + CodeTemplate.java_template.get( "default_response_filename_postfix") content["dto_elems"] = [] content["need_import_module"] = [] CodeGenerator.setResponsePropertyStyle(target) # 是否包含list类型字段 tmp_type = dto_field_type.lower() if tmp_type in ["list", "array"]: if lv2_need_create_nest_dto and "list" not in lv2_nest_dto_import_module: lv2_nest_dto_import_module.append("list") elif need_create_nest_dto and "list" not in nest_dto_import_module: nest_dto_import_module.append("list") else: if "list" not in need_import_module: need_import_module.append("list") dir_path = CodeTemplate.java_template.get( "default_file_path" ).get("output_" + target) % CodeGenerator.service_name if not os.path.exists(dir_path): os.makedirs(dir_path) # 为Array、List字段生成独立的dto文件 # 并使后续的小数点字段进入该dto内部 # 不支持嵌套array的情况, 所以这里只有为false时,才会生成dto, 否则前面生成的数据会被覆盖 if not need_create_nest_dto: nest_dto_filename = CamelTransformTool.trans_underline_field_to_camel_classname( dto_field_name) + "DTO" nest_dto_fp = open( dir_path + nest_dto_filename + ".java", "w+") nest_dto_elems = [] nest_dto_import_module = [] elif not lv2_need_create_nest_dto: lv2_nest_dto_filename = CamelTransformTool.trans_underline_field_to_camel_classname( dto_field_name) + "DTO" lv2_nest_dto_fp = open( dir_path + lv2_nest_dto_filename + ".java", "w+") lv2_nest_dto_elems = [] lv2_nest_dto_import_module = [] # 是否包含date类型 if tmp_type in ["t", "d", "date"]: if lv2_need_create_nest_dto and "date" not in lv2_nest_dto_import_module: lv2_nest_dto_import_module.append("date") elif need_create_nest_dto and "date" not in nest_dto_import_module: nest_dto_import_module.append("date") else: if "date" not in need_import_module: need_import_module.append("date") # 是否包含decimal类型 if tmp_type in ["b", "decimal", "bigdecimal"]: if lv2_need_create_nest_dto and "big_decimal" not in lv2_nest_dto_import_module: lv2_nest_dto_import_module.append("big_decimal") elif need_create_nest_dto and "big_decimal" not in nest_dto_import_module: nest_dto_import_module.append("big_decimal") else: if "big_decimal" not in need_import_module: need_import_module.append("big_decimal") if dto_field_name is None or dto_field_type is None: logger.error( "dto_field_name or dto_field_type miss, please check you protocol file" ) continue dto_elem = { "name": dto_field_name, "type": dto_field_type, "comment": dto_field_comment, } # 如果是嵌套的,则进入嵌套文件DTO中 if lv2_need_create_nest_dto: lv2_nest_dto_elems.append(dto_elem) elif need_create_nest_dto: nest_dto_elems.append(dto_elem) else: content["dto_elems"].append(dto_elem) # 单个sheet处理结束后,把未生成的文件生成出来 # 一层嵌套 if need_create_nest_dto and not CommonUtil.is_empty( nest_dto_fp): nest_dto_content = { "sheet_name": nest_dto_filename, "dto_elems": nest_dto_elems, "need_import_module": nest_dto_import_module, } CodeGenerator.gen_code(nest_dto_content, target) # 二层嵌套 if lv2_need_create_nest_dto and not CommonUtil.is_empty( lv2_nest_dto_fp): lv2_nest_dto_content = { "sheet_name": lv2_nest_dto_filename, "dto_elems": lv2_nest_dto_elems, "need_import_module": lv2_nest_dto_import_module, } CodeGenerator.gen_code(lv2_nest_dto_content, target) if dto_num > 0: content["need_import_module"] = need_import_module protocol_data.append(content) index += 1 return protocol_data else: logger.error("protocol_file=%s not exist" % protocol_file) print "protocol_file=%s not exist" % protocol_file return []
def gen_body(fp, sheet): """ 生成代码主体 :param sheet: :param fp: """ sheet_name = sheet.get("sheet_name") dto_elems = sheet.get("dto_elems") if dto_elems is not None and sheet_name is not None: classname = sheet_name CodeGenerator.class_define_begin(fp, classname) for elem in dto_elems: elem_type = TypeDict.type_dict.get(elem.get("type").lower()) if elem_type is None: logger.error("Unknown or miss field type, elem=%s" % str(elem)) continue elem_field_name = CamelTransformTool.trans_underline_field_to_camel_field( elem.get("name")) if elem_field_name is None: logger.error("miss field_name, elem=%s" % str(elem)) continue # 定义属性 elem_property_comment = elem.get("comment") CodeGenerator.property_comment(fp, elem_property_comment) # 在属性上添加注解, 默认的注解方式 if CodeTemplate.java_template.get( "style_json_property" ) == Constant.json_property_style.get("above_property"): CodeGenerator.json_property(fp, elem.get("name")) CodeGenerator.property_define(fp, elem_type, elem_field_name) for elem in dto_elems: elem_type = TypeDict.type_dict.get(elem.get("type").lower()) elem_field_name = CamelTransformTool.trans_underline_field_to_camel_field( elem.get("name")) elem_field_name_cap = CamelTransformTool.trans_underline_field_to_camel_classname( elem.get("name")) if elem_type is None or elem_field_name is None: continue # 定义set函数 elem_property_comment = elem.get("comment") CodeGenerator.function_comment(fp, elem_field_name, elem_property_comment) if CodeTemplate.java_template.get( "style_json_property" ) == Constant.json_property_style.get( "above_function_set_upper_case"): CodeGenerator.json_property(fp, elem.get("name")) if CodeTemplate.java_template.get( "style_json_property" ) == Constant.json_property_style.get( "above_function_set_lower_case"): CodeGenerator.json_property(fp, elem_field_name) CodeGenerator.json_serialize(fp) CodeGenerator.function_define_set(fp, elem_type, elem_field_name, elem_field_name_cap) # 定义get函数 CodeGenerator.function_comment(fp) if CodeTemplate.java_template.get( "style_json_property" ) == Constant.json_property_style.get( "above_function_set_upper_case"): CodeGenerator.json_property(fp, elem_field_name) if CodeTemplate.java_template.get( "style_json_property" ) == Constant.json_property_style.get( "above_function_set_lower_case"): CodeGenerator.json_property(fp, elem.get("name")) CodeGenerator.json_serialize(fp) CodeGenerator.function_define_get(fp, elem_type, elem_field_name, elem_field_name_cap) CodeGenerator.class_define_end(fp)