/** * Alipay.com Inc. * Copyright (c) 2004-2012 All Rights Reserved. */ package com.alipay.zdal.rule.config.beans; import groovy.lang.Binding; import groovy.lang.GroovyShell; import java.util.ArrayList; import java.util.List; import org.codehaus.groovy.control.CompilationFailedException; import com.alipay.zdal.common.util.TableSuffixTypeEnum; import com.alipay.zdal.rule.config.beans.TableRule.ParseException; /** * ��������±� * @author liang.chenl * */ public class SuffixManager { private List<Suffix> listSuffix = new ArrayList<Suffix>(); private String tbSuffix; private Binding binding = new Binding(); private GroovyShell shell = new GroovyShell(binding); public SuffixManager() { Suffix suf = new Suffix(); listSuffix.add(suf); } public List<Suffix> getListSuffix() { return listSuffix; } public void init(String[] dbIndexes) { Suffix suf = listSuffix.get(0); if (suf.getTbSuffixTo() == -1) { //tbSuffixToĬ�ϸ���dbIndex�ĸ������� suf.setTbSuffixTo(dbIndexes); } suf.setTbType(TableSuffixTypeEnum.throughAllDB.getValue()); //suf.setTbNumForEachDb(tbNumForEachDb); } /** * ����һ��range [_00-_99] * @param part * @param suf * @throws ParseException */ protected void parseOneRange(String part, Suffix suf, int dbIndexSize) throws ParseException { if (!part.startsWith("[") || !part.endsWith("]")) { throw new ParseException(); } //ȥ��[] part = part.substring(1, part.length() - 1); String[] temp = part.split("-"); if (temp.length != 2) { throw new ParseException(); } temp[0] = temp[0].trim(); temp[1] = temp[1].trim(); int firstNumFrom = firstNum(temp[0]); int firstNot0From = firstNot0(temp[0], firstNumFrom); int firstNumTo = firstNum(temp[1]); int firstNot0To = firstNot0(temp[1], firstNumTo); if (firstNumFrom == -1 || firstNumTo == -1) { throw new ParseException(); } if (firstNumFrom != firstNumTo) { throw new ParseException("padding width different"); } if (temp[0].length() != temp[1].length() && !( //_0-_16 (firstNot0From == -1 && firstNumFrom == temp[0].length() - 1 && firstNot0To == firstNumTo) //_1-_16 || (firstNot0From == firstNumFrom && firstNot0To == firstNumTo))) { throw new ParseException("tbSuffix width different"); } if (firstNumFrom != 0) { String fromPadding = temp[0].substring(0, firstNumFrom); String toPadding = temp[1].substring(0, firstNumTo); if (!fromPadding.equals(toPadding)) { throw new ParseException("padding different"); } suf.setTbSuffixPadding(fromPadding); } else { suf.setTbSuffixPadding(""); } int tbSuffixFrom = firstNot0From == -1 ? 0 //_0-_16 : Integer.parseInt(temp[0].substring(firstNot0From)); suf.setTbSuffixFrom(tbSuffixFrom); int tbSuffixTo = Integer.parseInt(temp[1].substring(firstNot0To)); suf.setTbSuffixTo(tbSuffixTo); if (tbSuffixTo <= tbSuffixFrom) { throw new ParseException(); } int tbSuffixWidth = temp[0].length() != temp[1].length() ? 0 : temp[0].length() - firstNumFrom; suf.setTbSuffixWidth(tbSuffixWidth); int tbNumForEachDb = -1; if (TableSuffixTypeEnum.resetForEachDB.getValue().equals(suf.getTbType())) { tbNumForEachDb = -1; } else { tbNumForEachDb = (tbSuffixTo - tbSuffixFrom + 1) / dbIndexSize; } suf.setTbNumForEachDb(tbNumForEachDb); } /** * ����֧��2�еı��� (twoColumnForEachDB: [_00-_99],[_00-_11]) * @param dbIndexes * @throws ParseException */ protected void parseTwoColumn(String part2, int dbIndexSize) throws ParseException { Suffix suf = listSuffix.get(0); String[] parts = part2.split(","); if (parts.length != 2) { throw new ParseException("twoColumnForEachDB must have two range"); } int tbNumForEachDb = -1; parseOneRange(parts[0], suf, dbIndexSize); suf.setTbNumForEachDb(tbNumForEachDb); Suffix suf2 = new Suffix(); parseOneRange(parts[1], suf2, dbIndexSize); suf2.setTbNumForEachDb(tbNumForEachDb); listSuffix.add(suf2); } /** * ������dbindexһ���±�ı��� * @param dbIndexes * @throws ParseException */ protected void parseDbIndex(String part2, int dbIndexSize) throws ParseException { Suffix suf = listSuffix.get(0); parseOneRange(part2, suf, dbIndexSize); suf.setTbNumForEachDb(-1); } protected void parseTbSuffix(String[] dbIndexes) throws ParseException { Suffix suf = listSuffix.get(0); String type; //�зַֿ�ģʽ�;����׺��ֵ String[] temp = tbSuffix.split(":"); if (TableSuffixTypeEnum.groovyAdjustTableList.getValue().equals(temp[0].trim())) { if (temp.length != 3) { throw new ParseException(); } } else { if (temp.length != 2) { throw new ParseException(); } } //�ֱ�ģʽ type = temp[0].trim(); suf.setTbType(type); //�ֱ�ľ���ģʽ�ֶ� String part2 = temp[1].trim(); if (TableSuffixTypeEnum.twoColumnForEachDB.getValue().equals(type)) { //���������ֱ� parseTwoColumn(part2, dbIndexes.length); } else if (TableSuffixTypeEnum.dbIndexForEachDB.getValue().equals(type)) { //����dbIndex�ֱ� parseDbIndex(part2, dbIndexes.length); } else if (TableSuffixTypeEnum.groovyTableList.getValue().equals(type)) { parseGroovyDbindex(part2); //����ĸ�������Ϊ -1����Ĭ��ÿ���ⶼ��ʼ��ȫ���ı� suf.setTbNumForEachDb(-1); } else if (TableSuffixTypeEnum.groovyThroughAllDBTableList.getValue().equals(type)) { parseGroovyDbindex(part2); } else if (TableSuffixTypeEnum.groovyAdjustTableList.getValue().equals(type)) { //����������÷�ʽ //����groovy�ű� String groovyExpression = temp[2].trim(); parseGroovyDbindex(groovyExpression); } else { //����ǰ���߼���ÿ�����ڵı���һ�µ� parseOneRange(part2, suf, dbIndexes.length); } } private void parseGroovyDbindex(String part2) throws ParseException { try { // listSuffix.get(0).setTbType(TableSuffixTypeEnum.groovyTableList.getValue()); shell.parse(part2); } catch (CompilationFailedException e) { throw new ParseException("groovy script with syntax error!"); } } public String getExpression() throws ParseException { String[] temp = tbSuffix.split(":"); if (TableSuffixTypeEnum.groovyAdjustTableList.getValue().equals(temp[0].trim())) { if (temp.length != 3) { throw new ParseException(); } return temp[1].trim() + ":" + temp[2].trim(); } else { if (temp.length != 2) { throw new ParseException(); } return temp[1].trim(); } } private static int firstNum(String str) { char c; for (int i = 0; i < str.length(); i++) { c = str.charAt(i); if (c >= '0' && c <= '9') { return i; } } return -1; } private static int firstNot0(String str, int start) { char c; for (int i = start; i < str.length(); i++) { c = str.charAt(i); if (c != '0') { return i; } } return -1; } public Suffix getSuffix(int index) { return listSuffix.get(index); } public String getTbSuffix() { return tbSuffix; } public void setTbSuffix(String tbSuffix) { this.tbSuffix = tbSuffix; } }