All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alipay.rdf.file.loader.TemplateLoader Maven / Gradle / Ivy

There is a newer version: 2.2.11
Show newest version
package com.alipay.rdf.file.loader;

import com.alibaba.fastjson.JSON;
import com.alipay.rdf.file.condition.RowConditionType;
import com.alipay.rdf.file.exception.RdfErrorEnum;
import com.alipay.rdf.file.exception.RdfFileException;
import com.alipay.rdf.file.interfaces.RowValidator;
import com.alipay.rdf.file.meta.FileBodyMeta;
import com.alipay.rdf.file.meta.FileColumnAttribute;
import com.alipay.rdf.file.meta.FileColumnMeta;
import com.alipay.rdf.file.meta.FileColumnRangeMeta;
import com.alipay.rdf.file.meta.FileColumnTypeMeta;
import com.alipay.rdf.file.meta.FileMeta;
import com.alipay.rdf.file.meta.MultiBodyConfig;
import com.alipay.rdf.file.meta.TemplateConfig;
import com.alipay.rdf.file.model.FileConfig;
import com.alipay.rdf.file.model.FileDataTypeEnum;
import com.alipay.rdf.file.model.FileDefaultConfig;
import com.alipay.rdf.file.model.RowCondition;
import com.alipay.rdf.file.util.RdfFileUtil;

import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Copyright (C) 2013-2018 Ant Financial Services Group
 *
 * 模板加载, 解析
 *
 * @author hongwei.quhw
 * @version $Id: TemplateLoader.java, v 0.1 2016-12-20 下午5:21:48 hongwei.quhw Exp $
 */
public class TemplateLoader {
    public static final Map CACHE            = new ConcurrentHashMap();

    public static final Map  ROW_LENGTH_CACHE = new ConcurrentHashMap();

    private static final Object               LOCK             = new Object();

    /**
     * 计算行总长度
     *
     * @param fileConfig
     * @return
     */
    public static int getRowLength(FileConfig fileConfig) {
        Integer len = ROW_LENGTH_CACHE.get(fileConfig.getTemplatePath());

        if (null == len) {
            FileMeta fileMeta = load(fileConfig);
            len = 0;
            for (FileColumnMeta colMeta : fileMeta.getBodyColumns()) {
                len += colMeta.getRange().getFirstAttr();
            }
            ROW_LENGTH_CACHE.put(fileConfig.getTemplatePath(), len);
        }

        return len;
    }

    /**
     * 加载模板
     *
     * @param fileConfig
     * @return
     */
    public static FileMeta load(FileConfig fileConfig) {
        return load(fileConfig.getTemplatePath(), fileConfig.getTemplateEncoding());
    }

    /**
     * 加载模板
     *
     * @param templatePath
     * @param templateEncoding
     * @param templateEncoding
     * @return
     */
    public static FileMeta load(String templatePath, String templateEncoding) {
        if (RdfFileUtil.isBlank(templateEncoding)) {
            templateEncoding = FileDefaultConfig.DEFAULT_TEMPLATE_ENCONDIG;
        }

        templatePath = ResourceLoader.buildResource(templatePath,
            FileDefaultConfig.RDF_TEMPLATE_PATH);

        FileMeta fileMeta = CACHE.get(templatePath);

        if (null != fileMeta) {
            return fileMeta;
        }

        synchronized (LOCK) {
            fileMeta = CACHE.get(templatePath);
            if (null != fileMeta) {
                return fileMeta;
            }

            InputStream is = ResourceLoader.getInputStream(templatePath);

            RdfFileUtil.assertNotNull(is, "rdf-file#模板不存在 templatePath=" + templatePath);

            String content = RdfFileUtil.safeReadFully(is, templateEncoding);
            TemplateConfig templateConfig = JSON.parseObject(content, TemplateConfig.class);

            fileMeta = new FileMeta();
            fileMeta.setTemplatePath(templatePath);

            int colIndex = 0;
            //head
            for (String head : templateConfig.getHead()) {
                fileMeta.addHeadColumn(parseFileColumn(templatePath, head, colIndex++, fileMeta, FileDataTypeEnum.HEAD));
            }

            // body 配置多模板解析
            if (templateConfig.getMultiBodys().size() > 0) {
                fileMeta.setMultiBody(true);
                for (MultiBodyConfig bodyConfig : templateConfig.getMultiBodys()) {
                    // body
                    FileBodyMeta bodyMeta = new FileBodyMeta();
                    RdfFileUtil.assertNotBlank(
                        bodyConfig.getName(), "rdf-file#multiTempalte config templatePath="
                                              + templatePath + ", bodyConfig name is blank");
                    bodyMeta.setName(bodyConfig.getName());
                    bodyMeta.setTemplatePath(templatePath);
                    colIndex = 0;
                    for (String body : bodyConfig.getBodyColumns()) {
                        bodyMeta.getColumns()
                            .add(parseFileColumn(templatePath, body, colIndex++, fileMeta, FileDataTypeEnum.BODY));
                    }
                    fileMeta.addBodyColumn(bodyMeta);

                    // 解析行条件
                    RdfFileUtil.assertNotBlank(bodyConfig.getCondition(),
                        "rdf-file#TemplateLoader 多模板配置 path=" + templatePath + " bodyTempateName="
                                                                          + bodyMeta.getName()
                                                                          + " 没有配置condition");
                    RowCondition rowCondition = new RowCondition(fileMeta, bodyConfig.getName(),
                        bodyConfig.getCondition(), RowConditionType.MULTI_BODY_TEMPLATE);
                    bodyMeta.setRowCondition(RowConditionLoader.loadRowCondition(rowCondition));
                }
            }

            // body单模板解析
            if (templateConfig.getBody().size() > 0) {
                if (fileMeta.isMultiBody()) {
                    throw new RdfFileException(
                        "rdf-file#TemplateLoader 数据定义模板,不支持同时定义body和multiBodys属性",
                        RdfErrorEnum.TEMPLATE_ERROR);
                }
                colIndex = 0;
                // body
                FileBodyMeta bodyMeta = new FileBodyMeta();
                for (String body : templateConfig.getBody()) {
                    bodyMeta.getColumns()
                        .add(parseFileColumn(templatePath, body, colIndex++, fileMeta, FileDataTypeEnum.BODY));
                }
                fileMeta.addBodyColumn(bodyMeta);
            }

            colIndex = 0;
            //tail
            for (String tail : templateConfig.getTail()) {
                fileMeta.addTailColumn(parseFileColumn(templatePath, tail, colIndex++, fileMeta, FileDataTypeEnum.TAIL));
            }

            colIndex = 0;
            // protocolDataType
            for (String dataType : templateConfig.getProtocolDataType()) {
                fileMeta.addProtocolDataType(parseFileColumn(templatePath, dataType, colIndex++, fileMeta, FileDataTypeEnum.UNKOWN));
            }

            //解析汇总字段
            for (String summaryColumnPair : templateConfig.getSummaryColumnPairs()) {
                fileMeta.addSummaryColumnPair(
                    SummaryLoader.parseSummaryPairMeta(fileMeta, summaryColumnPair));
            }

            //解析统计字段
            for (String statisticColumnPair : templateConfig.getStatisticColumnPairs()) {
                fileMeta.addStatisticPair(
                    SummaryLoader.parseStatisticPairMeta(fileMeta, statisticColumnPair));
            }

            //解析协议
            fileMeta.setProtocol(RdfFileUtil.assertTrimNotBlank(templateConfig.getProtocol()));

            //解析行校验器
            for (String rowValidator : templateConfig.getRowValidators()) {
                fileMeta.addRowValidator((RowValidator) RdfFileUtil.newInstance(rowValidator));
            }

            //解析startWithSplit
            if (RdfFileUtil.isNotBlank(templateConfig.getStartWithSplit())) {
                parseStartWithSplit(fileMeta, templateConfig.getStartWithSplit());
            }

            //解析endWithSplit
            if (RdfFileUtil.isNotBlank(templateConfig.getEndWithSplit())) {
                parseEndWithSplit(fileMeta, templateConfig.getEndWithSplit());
            }

            fileMeta.setColumnSplit(templateConfig.getColumnSplit());
            fileMeta.setFileEncoding(templateConfig.getFileEncoding());
            fileMeta.setLineBreak(templateConfig.getLineBreak());
            fileMeta.setAppendLinebreakAtLast(Boolean.valueOf(templateConfig.getIsAppendLinebreakAtLast()));
            fileMeta.setRelationReadRowCompatibility(templateConfig.getRelationReadRowCompatibility());
            if (RdfFileUtil.isNotBlank(templateConfig.getRowCodecMode())) {
                fileMeta.setRowCodecMode(templateConfig.getRowCodecMode());
            }

            // 参数
            fileMeta.setParams(templateConfig.getParams());

            CACHE.put(templatePath, fileMeta);

            return fileMeta;
        }
    }

    private static void parseStartWithSplit(FileMeta fileMeta, String startSplit) {
        String[] types = startSplit.split("\\|");
        for (String type : types) {
            if (type.equalsIgnoreCase("head")) {
                fileMeta.setStartWithSplit(FileDataTypeEnum.HEAD, true);
            } else if (type.equalsIgnoreCase("body")) {
                fileMeta.setStartWithSplit(FileDataTypeEnum.BODY, true);
            } else if (type.equalsIgnoreCase("tail")) {
                fileMeta.setStartWithSplit(FileDataTypeEnum.TAIL, true);
            }
        }
    }

    private static void parseEndWithSplit(FileMeta fileMeta, String startSplit) {
        String[] types = startSplit.split("\\|");
        for (String type : types) {
            if (type.equalsIgnoreCase("head")) {
                fileMeta.setEndWithSplit(FileDataTypeEnum.HEAD, true);
            } else if (type.equalsIgnoreCase("body")) {
                fileMeta.setEndWithSplit(FileDataTypeEnum.BODY, true);
            } else if (type.equalsIgnoreCase("tail")) {
                fileMeta.setEndWithSplit(FileDataTypeEnum.TAIL, true);
            }
        }
    }

    private static FileColumnMeta parseFileColumn(String tempaltePath, String colConfig,
                                                  int colIndex, FileMeta fileMeta, FileDataTypeEnum dataType) {
        colConfig = RdfFileUtil.assertTrimNotBlank(colConfig, "字段为空 index=" + colIndex);

        String[] fields = colConfig.trim().split("\\|");

        String key = fields[0];

        //如果只定义了1列, 则key和name都是使用相同的内容
        String name = fields.length > 1 ? fields[1] : key;

        FileColumnTypeMeta type = null;
        boolean required = false;
        FileColumnRangeMeta range = null;
        String defaultValue = null;

        if (fields.length > 2) {
            for (int i = 2; i < fields.length; i++) {
                String field = fields[i];
                int semicolonIndex = field.indexOf(":");
                String extra = null;
                if (semicolonIndex > 0) {
                    extra = field.substring(semicolonIndex + 1);
                    field = field.substring(0, semicolonIndex);
                }

                field = RdfFileUtil.assertTrimNotBlank(field,
                    "rdf-dal#TemplateLoader tempaltePath=" + tempaltePath + ", 字段定义[" + colConfig
                                                              + "], index=" + colIndex
                                                              + ", 为空请检查数据定义模板");

                // 尝试解析类型属性
                FileColumnTypeMeta typeMeta = FileColumnTypeMeta.tryValueOf(field, extra);
                if (null != typeMeta) {
                    type = typeMeta;
                    continue;
                }

                //配置了范围属性
                FileColumnRangeMeta rangeMeta = FileColumnRangeMeta.tryValueOf(field, extra);
                if (null != rangeMeta) {
                    range = rangeMeta;
                    continue;
                }

                //配置了必读属性
                if (FileColumnAttribute.REQUIRED.name().equalsIgnoreCase(field)) {
                    if (RdfFileUtil.isBlank(extra)) {
                        required = true;
                    } else {
                        required = Boolean.valueOf(extra);
                    }

                    continue;
                }

                //配置默认值
                if (FileColumnAttribute.DEFAULT.name().equalsIgnoreCase(field)) {
                    defaultValue = RdfFileUtil.assertTrimNotBlank(extra);
                    continue;
                }

                throw new RdfFileException("请检查模板配置, 无法匹配属性! 字段=" + field + ", index=" + colIndex,
                    RdfErrorEnum.TEMPLATE_ERROR);
            }
        }

        //如果没有定义数据类型,默认string
        if (null == type) {
            type = new FileColumnTypeMeta("String", null);
        }

        FileColumnMeta column = new FileColumnMeta(colIndex, key, name, type, required, range,
            defaultValue, fileMeta, dataType);

        return column;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy