package com.mfh.comn.code; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.StringUtils; /** * 统一编码串,通过字符分割体现层次;统一编码串各段可以位于同一张表或跨表。 * 跨表时通过_T_分割,表内通过_DOWN_分割。 * * @author zhangyz created on 2013-1-25 * @since Framework 1.0 */ public class UnionCode { public static String CODE_T_DEVIDE = "_T_"; public static String DOWN = "_DOWN_"; private List<String[]> segs = null; /** * 是否存在多个表 * @param code * @return * @author zhangyz created on 2012-5-8 */ public static boolean haveMutiTable(String code){ if (code.indexOf(CODE_T_DEVIDE) > 0) return true; else return false; } /** * 是否存在多个层 * @param code * @return * @author zhangyz created on 2012-5-9 */ public static boolean haveMutiDeep(String code){ if (code.indexOf(CODE_T_DEVIDE) > 0 || code.indexOf(DOWN) > 0) return true; else return false; } /** * 直接按原始编码串进行初始化 * @param code 格式如: 11_T_01_DOWN_0001_DONW_000002,其中_T_分隔的可能不存在。 */ public UnionCode(String code) { super(); if (code == null || code.length() == 0) return; if (code.indexOf(CODE_T_DEVIDE) >= 0){ String[] lts = StringUtils.splitByWholeSeparator(code, CODE_T_DEVIDE); segs = new ArrayList<String[]>(lts.length); for (int ii = 0; ii < lts.length; ii++){ String [] vars = StringUtils.splitByWholeSeparator(lts[ii], DOWN); segs.add(vars); } } else{ segs = new ArrayList<String[]>(1); String[] vars = StringUtils.splitByWholeSeparator(code, DOWN);//temp.split(Constants.DOWN); segs.add(vars); } } /** * 无参构造函数,后面通过调用addCodeSegment和newCodeDivide进行编码初始化工作。 */ public UnionCode() { segs = new ArrayList<String[]>(); } /** * 在调用无参构造函数后,可以连续调用该方法,所以返回类本身。 * @param segment 编码段,按从左到右顺序可以有多段,每段都需要调用本方法添加。 * @return * @author zhangyz created on 2014-3-19 */ public UnionCode addCodeSegment(String segment) { if (segs.size() == 0) segs.add(new String[] {}); int dividePos = segs.size() - 1; String[] segArray = segs.get(dividePos); int oldSize = segArray.length; String[] newArray = new String[oldSize + 1]; System.arraycopy(segArray, 0, newArray, 0, oldSize); newArray[oldSize] = segment; segs.set(dividePos, newArray); return this; } /** * 在调用无参构造函数后,可以调用该方法。启用一个新的表分隔,意味着该编码会跨表。后面调用addCodeSegment()添加的编码段都位于该新的表分隔下。 * @return * @author zhangyz created on 2014-3-19 */ public UnionCode newCodeDivide() { if (segs.size() == 0) { segs.add(new String[] {}); return this; } else { String[] segArray = segs.get(segs.size() - 1); if (segArray.length == 0) return this;//无须添加,说明可能是误调用。 segs.add(new String[] {}); } return this; } /** * 该编码串涉及到几张表 * @return * @author zhangyz created on 2012-4-15 */ public int getCodePartSize(){ if (segs == null) return 0; return segs.size(); } /** * 获取指定位置表的编码串 * @param index 属于哪个表的;默认为0,代表只有一个表 * @return * @author zhangyz created on 2012-4-10 */ public String[] getCodeInOneTable(int index){ if (segs == null) return null; if (index >= segs.size()) return null; return segs.get(index); } /** * 获取指定位置表的编码串 * @param index 属于哪个表的;默认为0,代表只有一个表 * @param index * @param assertLength 断定返回串有几个 * @return * @author zhangyz created on 2012-5-29 */ public String[] getCodeInOneTable(int index, int assertLength){ if (segs == null) return null; if (index >= segs.size()) return null; String[] ret = segs.get(index); if (ret == null || ret.length != assertLength) throw new RuntimeException("不正确的codeId查询参数,应有" + assertLength + "段!"); return ret; } /** * 获取最后一部分的统一编码串;各部分是可以独立存在的 * * @author zhangyz created on 2012-5-30 */ public String getUnCodeInLastTable(){ if (segs == null) return null; String[] rets = segs.get(segs.size() - 1); if (rets.length == 1) return rets[0]; StringBuilder builder = new StringBuilder(rets[0]); for (int ii = 1; ii < rets.length; ii++){ builder.append(DOWN).append(rets[ii]); } return builder.toString(); } /** * 获取最后一部分的编码串数组 * @return * @author zhangyz created on 2012-4-10 */ public String[] getCodeInLastTable(){ if (segs == null) return null; return segs.get(segs.size() - 1); } /** * 获取最后一部分的编码串 * @param assertLength 断定返回串有几个 * @return * @author zhangyz created on 2012-5-29 */ public String[] getCodeInLastTable(int assertLength){ if (segs == null) return null; String[] ret = segs.get(segs.size() - 1); if (ret == null || ret.length != assertLength) throw new RuntimeException("不正确的codeId查询参数,应有" + assertLength + "段!"); return ret; } /** * 针对某父子关系的编码串,取其最后一层值作为编码值 * @param index 属于哪个表的,默认为0,代表只有一个表 * @return * @author zhangyz created on 2012-4-11 */ public String getLastCodeInOneTable(int index){ if (segs == null) return null; if (index >= segs.size()) return null; String[] strs = segs.get(index); return strs[strs.length - 1]; } @Override public String toString() { if (segs == null) return null; StringBuilder ret = new StringBuilder(); for (String[] item : segs) { if (ret.length() > 0) ret.append(CODE_T_DEVIDE); for (int ii = 0; ii < item.length; ii++) { if (ii > 0) ret.append(DOWN); ret.append(item[ii]); } } return ret.toString(); } /** * 直接获取统一编码串的最后一小段. * @param code * @return * @author zhangyz created on 2012-6-25 */ public static String getLastCodeInLastTable(String code){ if (code == null || code.length() == 0) return null; int tn = code.lastIndexOf(CODE_T_DEVIDE); int dn = code.lastIndexOf(DOWN); int inLength = 0; if(tn > dn) { inLength = tn; inLength += CODE_T_DEVIDE.length(); } else if(dn > tn) { inLength = dn; inLength += DOWN.length(); } else if (tn == -1) return code; code = code.substring(inLength); return code; } /** * 针对统一编码串中最后部分的父子关系的编码串,取其最后一层值作为编码值 * @return * @author zhangyz created on 2012-4-11 */ public String getLastCodeInLastTable(){ if (segs == null) return null; String[] strs = segs.get(segs.size() - 1); return strs[strs.length - 1]; } /** * 断言传入的当前编码值参数串应该有几段 * * @param segs 已解析的编码串 * @param length * @return 返回传入的参数,便于后续级联操作 * @author zhangyz created on 2012-4-12 */ public static String[] assertParam(String[] segs, int length) { if(segs == null || segs.length != length) throw new RuntimeException((new StringBuilder("传入的字符串数组应该是")).append(length).append("段!").toString()); else return segs; } public static List<String> assertParam(List<String> segs, int length) { if(segs == null || segs.size() != length) throw new RuntimeException((new StringBuilder("传入的字符串列表应该是")).append(length).append("段!").toString()); else return segs; } }