content: package com.alipay.rdf.file.meta;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  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.model.FileDataTypeEnum;
  import com.alipay.rdf.file.util.RdfFileUtil;
  
  /**
   * Copyright (C) 2013-2018 Ant Financial Services Group
   *
   * 文件元数据
   *
   * @author hongwei.quhw
   * @version $Id: FileMeta.java, v 0.1 2016-12-20 下午4:08:31 hongwei.quhw Exp $
   */
  public class FileMeta {
      /** 文件总笔数 */
      public static final String             DEFAULT_TOTALCOUNTKEY = "totalCount";
      /** 协议*/
      private String                         protocol;
      /** 头部字段*/
      private final List<FileColumnMeta>     headColumns           = new ArrayList<FileColumnMeta>();
      /** 行记录字段*/
      private final List<FileBodyMeta>       bodyColumns           = new ArrayList<FileBodyMeta>();
      /** 尾部字段*/
      private final List<FileColumnMeta>     tailColumns           = new ArrayList<FileColumnMeta>();
  
      /** 模板路径*/
      private String                         templatePath;
  
      private final List<SummaryPairMeta>    summaryPairs          = new ArrayList<SummaryPairMeta>();
  
      private final List<StatisticPairMeta>  statisticPairs        = new ArrayList<StatisticPairMeta>();
  
      private final List<RowValidator>       validators            = new ArrayList<RowValidator>();
  
      private String                         lineBreak;
  
      private String                         columnSplit;
      /** 文件编码*/
      private String                         fileEncoding;
  
      private String                         totalCountKey         = DEFAULT_TOTALCOUNTKEY;
  
      private Map<FileDataTypeEnum, Boolean> startWithSplit        = new HashMap<FileDataTypeEnum, Boolean>();
  
      private Map<FileDataTypeEnum, Boolean> endWithSplit          = new HashMap<FileDataTypeEnum, Boolean>();
      /**body是否是多模板配置*/
      private boolean                        multiBody             = false;
      /**文件尾是否需要换行*/
      private boolean                        isAppendLinebreakAtLast = true;
      /**定义或者覆盖协议文件的字段类型*/
      private final List<FileColumnMeta>     protocolDataTypes     = new ArrayList<FileColumnMeta>();
      /**关系模式读行数据兼容模式*/
      private Boolean                        relationReadRowCompatibility;
      /**行序列化反序列化模式: 默认关系模式*/
      private String                         rowCodecMode = "relation";
      /**非通用参数，用于传递给插件*/
      private Map<String, String>            params = new HashMap<String, String>();
  
      public boolean isStartWithSplit(FileDataTypeEnum rowType) {
          Boolean startSplit = startWithSplit.get(rowType);
  
          if (null == startSplit) {
              return false;
          }
  
          return startSplit;
      }
  
      public boolean isEndWithSplit(FileDataTypeEnum rowType) {
          Boolean endSplit = endWithSplit.get(rowType);
  
          if (null == endSplit) {
              return false;
          }
  
          return endSplit;
      }
  
      public void setStartWithSplit(FileDataTypeEnum rowType, boolean startSplit) {
          startWithSplit.put(rowType, startSplit);
      }
  
      public void setEndWithSplit(FileDataTypeEnum rowType, boolean endSplit) {
          endWithSplit.put(rowType, endSplit);
      }
  
      public boolean hasColumns(FileDataTypeEnum rowType) {
          switch (rowType) {
              case HEAD:
                  return hasHead();
              case BODY:
                  return hasBody();
              case TAIL:
                  return hasTail();
              default:
                  throw new RdfFileException("不支持类似rowType=" + rowType.name(),
                      RdfErrorEnum.UNSUPPORTED_OPERATION);
          }
      }
  
      public List<FileColumnMeta> getColumns(FileDataTypeEnum rowType) {
          switch (rowType) {
              case HEAD:
                  return getHeadColumns();
              case BODY:
                  return getBodyColumns();
              case TAIL:
                  return getTailColumns();
              default:
                  throw new RdfFileException("不支持类似rowType=" + rowType.name(),
                      RdfErrorEnum.UNSUPPORTED_OPERATION);
          }
      }
  
      /**
       * 文件是否有头
       *
       * @return
       */
      public boolean hasHead() {
          return headColumns.size() > 0;
      }
  
      /**
       * 文件是否有文件体
       *
       * @return
       */
      public boolean hasBody() {
          return bodyColumns.size() > 0;
      }
  
      /**
       * 文件是否有文件尾
       *
       * @return
       */
      public boolean hasTail() {
          return tailColumns.size() > 0;
      }
  
      /**
       * 增加文件头
       *
       * @param column
       */
      public void addHeadColumn(FileColumnMeta column) {
          headColumns.add(column);
      }
  
      public FileColumnMeta getHeadColumn(String name) {
          for (FileColumnMeta colMeta : headColumns) {
              if (colMeta.getName().equals(name)) {
                  return colMeta;
              }
          }
  
          throw new RdfFileException("rdf-file#FileMeta.getHeadColumn(name=" + name + ") 有没有定义",
              RdfErrorEnum.COLUMN_NOT_DEFINED);
      }
  
      /**
       * 增加文件体
       *
       * @param bodyMeta
       */
      public void addBodyColumn(FileBodyMeta bodyMeta) {
          bodyColumns.add(bodyMeta);
      }
  
      /**
       * 增加文件尾
       *
       * @param column
       */
      public void addTailColumn(FileColumnMeta column) {
          tailColumns.add(column);
      }
  
      public FileColumnMeta getTailColumn(String name) {
          for (FileColumnMeta colMeta : tailColumns) {
              if (colMeta.getName().equals(name)) {
                  return colMeta;
              }
          }
  
          throw new RdfFileException("rdf-file#FileMeta.getTailColumn(name=" + name + ") 有没有定义",
              RdfErrorEnum.COLUMN_NOT_DEFINED);
      }
  
      public void addProtocolDataType(FileColumnMeta type) {
          protocolDataTypes.add(type);
      }
  
      /**
       * Getter method for property <tt>columnSplit</tt>.
       *
       * @return property value of columnSplit
       */
      public String getColumnSplit() {
          return columnSplit;
      }
  
      /**
       * Setter method for property <tt>columnSplit</tt>.
       *
       * @param columnSplit value to be assigned to property columnSplit
       */
      public void setColumnSplit(String columnSplit) {
          this.columnSplit = columnSplit;
      }
  
      /**
       * Getter method for property <tt>headColumns</tt>.
       *
       * @return property value of headColumns
       */
      public List<FileColumnMeta> getHeadColumns() {
          return headColumns;
      }
  
      /**
       * Getter method for property <tt>bodyColumns</tt>.
       *
       * @return property value of bodyColumns
       */
      public List<FileColumnMeta> getBodyColumns() {
          if (multiBody) {
              throw new RdfFileException(
                  "rdf-file#FileMeta.getBodyColumns() protocol=" + protocol + " 不支持body多模板配置.",
                  RdfErrorEnum.UNSUPPORTED_OPERATION);
          }
          return bodyColumns.get(0).getColumns();
      }
  
      public List<FileBodyMeta> getBodyMetas() {
          return this.bodyColumns;
      }
  
      public FileBodyMeta getBodyMeta(String bodyTemplateName) {
          if (multiBody) {
              for (FileBodyMeta bodyMeta : bodyColumns) {
                  if (bodyMeta.getName().equals(bodyTemplateName)) {
                      return bodyMeta;
                  }
              }
          } else {
              return bodyColumns.get(0);
          }
  
          return null;
      }
  
      public List<FileColumnMeta> getProtocolDataTypes() {
          return protocolDataTypes;
      }
  
      /**
       * Getter method for property <tt>tailColumns</tt>.
       *
       * @return property value of tailColumns
       */
      public List<FileColumnMeta> getTailColumns() {
          return tailColumns;
      }
  
      /**
       * Getter method for property <tt>templatePath</tt>.
       *
       * @return property value of templatePath
       */
      public String getTemplatePath() {
          return templatePath;
      }
  
      /**
       * Setter method for property <tt>templatePath</tt>.
       *
       * @param templatePath value to be assigned to property templatePath
       */
      public void setTemplatePath(String templatePath) {
          this.templatePath = templatePath;
      }
  
      /**
       * Getter method for property <tt>encoding</tt>.
       *
       * @return property value of encoding
       */
      public String getFileEncoding() {
          return fileEncoding;
      }
  
      /**
       * Setter method for property <tt>encoding</tt>.
       *
       * @param fileEncoding value to be assigned to property encoding
       */
      public void setFileEncoding(String fileEncoding) {
          this.fileEncoding = fileEncoding;
      }
  
      /**
       * Getter method for property <tt>totalCountKey</tt>.
       *
       * @return property value of totalCountKey
       */
      public String getTotalCountKey() {
          return totalCountKey;
      }
  
      /**
       * Setter method for property <tt>totalCountKey</tt>.
       *
       * @param totalCountKey value to be assigned to property totalCountKey
       */
      public void setTotalCountKey(String totalCountKey) {
          this.totalCountKey = totalCountKey;
      }
  
      /**
       * Getter method for property <tt>summaryPairs</tt>.
       *
       * @return property value of summaryPairs
       */
      public List<SummaryPairMeta> getSummaryPairMetas() {
          return summaryPairs;
      }
  
      /**
       * 增加合计列参数
       *
       * @param pair
       */
      public void addSummaryColumnPair(SummaryPairMeta pair) {
          this.summaryPairs.add(pair);
      }
  
      public List<StatisticPairMeta> getStatisticPairMetas() {
          return statisticPairs;
      }
  
      public void addStatisticPair(StatisticPairMeta pair) {
          this.statisticPairs.add(pair);
      }
  
      /**
       * Setter method for property <tt>protocol</tt>.
       *
       * @param protocol value to be assigned to property protocol
       */
      public void setProtocol(String protocol) {
          this.protocol = protocol;
      }
  
      /**
       * Getter method for property <tt>protocol</tt>.
       *
       * @return property value of protocol
       */
      public String getProtocol() {
          return protocol;
      }
  
      /**
       * Getter method for property <tt>validators</tt>.
       *
       * @return property value of validators
       */
      public List<RowValidator> getValidators() {
          return validators;
      }
  
      public void addRowValidator(RowValidator rowValidator) {
          validators.add(rowValidator);
      }
  
      public String getLineBreak() {
          return lineBreak;
      }
  
      public boolean isMultiBody() {
          return multiBody;
      }
  
      public void setMultiBody(boolean multiBody) {
          this.multiBody = multiBody;
      }
  
      public void setLineBreak(String lineBreak) {
          if ("\r\n".equals(lineBreak) || "\n".equals(lineBreak) || "\r".equals(lineBreak)) {
              this.lineBreak = lineBreak;
          } else if (RdfFileUtil.isNotBlank(lineBreak)) {
              throw new RdfFileException("rdf-file# 不支持换行符 lineBreak=" + lineBreak,
                  RdfErrorEnum.UNSUPPORT_LINEBREAK);
          }
      }
  
      public Boolean getRelationReadRowCompatibility() {
          return relationReadRowCompatibility;
      }
  
      public void setRelationReadRowCompatibility(Boolean relationReadRowCompatibility) {
          this.relationReadRowCompatibility = relationReadRowCompatibility;
      }
  
      public String getRowCodecMode() {
          return rowCodecMode;
      }
  
      public void setRowCodecMode(String rowCodecMode) {
          this.rowCodecMode = rowCodecMode;
      }
  
      public Map<String, String> getParams() {
          return params;
      }
  
      public void setParams(Map<String, String> params) {
          this.params = params;
      }
  
      @Override
      public String toString() {
          StringBuffer sb = new StringBuffer("FileMeta[");
          sb.append("protocol=" + protocol);
          sb.append(",templatePath=" + templatePath);
          sb.append("]");
          return sb.toString();
      }
  
      public boolean isAppendLinebreakAtLast() {
          return isAppendLinebreakAtLast;
      }
  
      public void setAppendLinebreakAtLast(boolean appendLinebreakAtLast) {
          isAppendLinebreakAtLast = appendLinebreakAtLast;
      }
  }
  