/* * Copyright 2008 biaoping.yin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.frameworkset.util; import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.frameworkset.util.ClassUtil; import org.frameworkset.util.ClassUtil.PropertieDescription; /** * <p>Title: VariableHandler.java</p> * <p>Description: 变量解析程序 </p> * <p>bboss workgroup</p> * <p>Copyright (c) 2008</p> * @Date 2009-12-16 上午11:34:31 * @author biaoping.yin * @version 1.0 */ public class VariableHandler { public static String default_regex = "\\$\\{(.+?)\\}"; private static String buildVariableRegex(String pretoken,String endtoken) { StringBuffer ret = new StringBuffer(); // ret.append(pretoken).append("([^").append(endtoken).append("]+)").append(endtoken); ret.append(pretoken).append("(.+?)").append(endtoken); return ret.toString(); } /** * 可以根据默认的正则式default_regex = "\\$\\{([^\\}]+)\\}"获取输入串中的变量,作为数组返回 * @param inputString * @return */ public static String[] variableParser(String inputString) { String[] vars = RegexUtil.containWithPatternMatcherInput(inputString, default_regex); return vars; } /** * 可以根据指定的变量的前导符和后导符获取输入串中的变量,作为数组返回 * @param inputString * @param pretoken * @param endtoken * @return */ public static String[] variableParser(String inputString,String pretoken,String endtoken) { // String regex = buildVariableRegex(pretoken,endtoken); // String[] vars = RegexUtil.containWithPatternMatcherInput(inputString, regex); // return vars; return variableParser( inputString,pretoken,endtoken,RegexUtil.default_mask); } /** * 可以根据指定的变量的前导符和后导符获取输入串中的变量,作为数组返回 * @param inputString * @param pretoken * @param endtoken * @return */ public static String[] variableParser(String inputString,String pretoken,String endtoken,int mask) { String regex = buildVariableRegex(pretoken,endtoken); String[] vars = RegexUtil.containWithPatternMatcherInput(inputString, regex,mask); return vars; } /** * 可以根据指定的正则式获取输入串中的变量,作为数组返回 * @param inputString * @param regex * @return */ public static String[] variableParser(String inputString,String regex) { // String regex = buildVariableRegex(pretoken,endtoken); String[] vars = RegexUtil.containWithPatternMatcherInput(inputString, regex); return vars; } /** * 从串src中析取匹配regex模式的所有字符串,并且用substitution替换匹配上模式的子符串 * @param src * @param regex * @param substitution * @return String[][]二维数组,第一维表示替换后的src,第二维表示匹配regex的所有的子串数组 */ public static String[][] parser2ndSubstitution(String inputString,String regex,String substitution) { return RegexUtil.contain2ndReplaceWithPatternMatcherInput(inputString, regex, substitution); } /** * 从串src中析取匹配regex模式的所有字符串,并且用substitution替换匹配上模式的子符串 * @param src * @param regex * @param substitution * @return String[][]二维数组,第一维表示替换后的src,第二维表示匹配regex的所有的子串数组 */ public static String[][] parser2ndSubstitution(String inputString,String substitution) { return RegexUtil.contain2ndReplaceWithPatternMatcherInput(inputString,default_regex , substitution); } /** * 从串src中析取匹配pretoken 变量定义前缀和endtoken 变量定义后缀指定模式所有字符串,并且用substitution替换匹配上模式的子符串 * @param inputString 输入的串 * @param pretoken 变量定义前缀 * @param endtoken 变量定义后缀 * @param substitution * @return String[][]二维数组,第一维表示替换后的src,第二维表示匹配regex的所有的子串数组 */ public static String[][] parser2ndSubstitution(String inputString,String pretoken,String endtoken ,String substitution) { String regex = buildVariableRegex(pretoken,endtoken); return RegexUtil.contain2ndReplaceWithPatternMatcherInput(inputString, regex, substitution,RegexUtil.default_mask); } /** * 从串src中析取匹配pretoken 变量定义前缀和endtoken 变量定义后缀指定模式所有字符串,并且用substitution替换匹配上模式的子符串 * @param inputString 输入的串 * @param pretoken 变量定义前缀 * @param endtoken 变量定义后缀 * @param substitution * @return String[][]二维数组,第一维表示替换后的src,第二维表示匹配regex的所有的子串数组 */ public static String[][] parser2ndSubstitution(String inputString,String pretoken,String endtoken ,String substitution,int mask) { String regex = buildVariableRegex(pretoken,endtoken); return RegexUtil.contain2ndReplaceWithPatternMatcherInput(inputString, regex, substitution,mask); } /** * 替换变量为制定的值 * @param inputString * @param substitution * @return */ public static String substitution(String inputString,String substitution) { return SimpleStringUtil.replaceAll(inputString, default_regex, substitution); } /** * 替换变量为制定的值 * @param inputString * @param substitution * @return */ public static String substitution(String inputString,String regex,String substitution) { return SimpleStringUtil.replaceAll(inputString, regex, substitution); } public static class URLStruction { protected List<String> tokens; protected List<Variable> variables; public List<String> getTokens() { return tokens; } public void setTokens(List<String> tokens) { this.tokens = tokens; } public List<Variable> getVariables() { return variables; } public void setVariables(List<Variable> variables) { this.variables = variables; } } public static class SQLStruction extends URLStruction{ private String sql; private boolean hasVars = true; public SQLStruction() { } public SQLStruction(String sql) { this.sql = sql; hasVars = false; } public boolean hasVars() { return this.hasVars; } public String buildSQL() { if(sql == null) { if(this.variables != null && variables.size() > 0) { StringBuffer sql_ = new StringBuffer(); int tsize = this.tokens.size(); int vsize = this.variables.size(); if(tsize == vsize) { for(int i = 0; i < vsize; i ++) { sql_.append(tokens.get(i)).append("?"); } } else //tsize = vsize + 1; { for(int i = 0; i < vsize; i ++) { sql_.append(tokens.get(i)).append("?"); } sql_.append(tokens.get(vsize)); } this.sql = sql_.toString(); } } return sql; } public String getSql() { return sql; } public void setSql(String sql) { this.sql = sql; } } public static class Variable { private String variableName; private int position; private List<Index> indexs; private Variable parent; private Variable next; public String getVariableName() { return variableName; } public void setVariableName(String variableName) { this.variableName = variableName; } public int getPosition() { return position; } public void setPosition(int position) { this.position = position; } public List<Index> getIndexs() { return indexs; } public void setIndexs(List<Index> indexs) { this.indexs = indexs; } public Variable getParent() { return parent; } public void setParent(Variable parent) { this.parent = parent; } public Variable getNext() { return next; } public void setNext(Variable next) { this.next = next; } public String toString() { StringBuffer ret = new StringBuffer(); ret.append(this.variableName); if(this.indexs != null && this.indexs.size() >0) { for(Index idx :indexs) { ret.append("[").append(idx.toString()).append("]"); } } if(next != null) { ret.append("->").append(next.toString()); } if(this.parent == null) ret.append(",position=").append(this.position); return ret.toString(); } } public static class Index { // private Object index; private int int_idx = -1; private String string_idx; public Index(int index) { super(); this.int_idx = index; } public Index(String index) { super(); this.string_idx = index; } public int getInt_idx() { return int_idx; } public String getString_idx() { return string_idx; } public String toString() { if(int_idx != -1) return int_idx + ""; else return string_idx; } } /** * 将包含变量的url路径解析成常量字符串列表和变量名称两个列表 * 变量的分界符为#[和],如果url中没有包含变量那么返回null值 * @param url * @return */ public static URLStruction parserURLStruction(String url) { if(url == null || url.trim().length() == 0) return null; int len = url.length(); int i = 0; StringBuffer token = new StringBuffer(); StringBuffer var = new StringBuffer(); boolean varstart = false; int varstartposition = -1; List<Variable> variables = new ArrayList<Variable>(); int varcount = 0; List<String> tokens = new ArrayList<String>(); while (i < len) { if (url.charAt(i) == '#') { if(i + 1 < len) { if( url.charAt(i + 1) == '[') { if (varstart) { token.append("#[").append(var); var.setLength(0); } varstart = true; i = i + 2; varstartposition = i; var.setLength(0); continue; } } } if (varstart) { if (url.charAt(i) == '&') { varstart = false; i++; token.append("#[").append(var); var.setLength(0); continue; } else if (url.charAt(i) == ']') { if (i == varstartposition) { varstart = false; i++; token.append("#[]"); continue; } else { Variable variable = new Variable(); variable.setPosition(varcount); variable.setVariableName(var.toString()); variables.add(variable); tokens.add(token.toString()); token.setLength(0); var.setLength(0); varcount++; varstart = false; i++; } } else { var.append(url.charAt(i)); i ++; } } else { token.append(url.charAt(i)); i ++; } } if (token.length() > 0) { if (var.length() > 0) { token.append("#[").append(var); } tokens.add(token.toString()); } else { if (var.length() > 0) { // token.append("#[").append(var); // tokens.add(token.toString()); token.append("#[").append(var); int idx = tokens.size() - 1; tokens.set(idx,tokens.get(idx)+token.toString()); } } if (variables.size() == 0) return null; else { URLStruction itemUrlStruction = new URLStruction(); itemUrlStruction.setTokens(tokens); itemUrlStruction.setVariables(variables); return itemUrlStruction; } } /** * 将包含变量的sql语句解析成常量字符串列表和变量名称两个列表 * 变量的分界符为#[和],如果url中没有包含变量那么返回null值 * 变量数组、list、map的元素取值采用[]结合数字下标和key名称 * 变量引用采用->连接符 * @param url * @return */ public static SQLStruction parserSQLStruction(String sql) { if(sql == null || sql.trim().length() == 0) return null; int len = sql.length(); int i = 0; StringBuffer token = new StringBuffer(); StringBuffer var = new StringBuffer(); // StringBuffer index = new StringBuffer(); boolean varstart = false; int varstartposition = -1;//记录变量的开始位置 //集合索引开始 boolean index_start = false; Variable header = null; Variable hh = null; Variable variable = null; List<Index> indexs = null; /** * 对象属性引用位置开始 */ boolean ref_start = false; List<Variable> variables = new ArrayList<Variable>(); int varcount = 0; List<String> tokens = new ArrayList<String>(); while (i < len) { if (sql.charAt(i) == '#') { if(i + 1 < len) { if( sql.charAt(i + 1) == '[') { if (varstart) {//fixed me String partvar = sql.substring(varstartposition,i); // token.append("#[").append(var); token.append("#[").append(partvar); var.setLength(0); } index_start = false; varstart = true; variable = null; header = null; header = null; hh = null; indexs = null; /** * 对象属性引用位置开始 */ ref_start = false; i = i + 2; varstartposition = i; var.setLength(0); continue; } } } if (varstart) { if (sql.charAt(i) == '[') { if(!ref_start) { if(!index_start) { header = new Variable(); header.setPosition(varcount); header.setVariableName(var.toString()); // variables.add(header); var.setLength(0); tokens.add(token.toString()); token.setLength(0); varcount++; index_start = true; indexs = new ArrayList<Index>(); header.setIndexs(indexs); hh = header; } else { //] } } else { if(!index_start) { variable = new Variable(); //variable.setPosition(varcount); variable.setVariableName(var.toString()); var.setLength(0); header.setNext(variable); variable.setParent(header); header = variable; index_start = true; indexs = new ArrayList<Index>(); header.setIndexs(indexs); } } i++; // token.append("#[").append(var); var.setLength(0); continue; } else if (sql.charAt(i) == ']') { if (i == varstartposition) { varstart = false; i++; token.append("#[]"); continue; } else { if(index_start) { String t = var.toString(); try{ int idx = Integer.parseInt(t); indexs.add(new Index(idx)); } catch(Exception e) { indexs.add(new Index(t)); } var.setLength(0); // index_start = false; if(i + 1 < len) { if(sql.charAt(i + 1) == ']') { index_start = false; indexs = null; // i ++; } } i++; } else if(ref_start)//引用结束,变量定义结束a->b[0] { ref_start = false; // if(sql.charAt(i + 1) == '-' && sql.charAt(i + 2) == '>') // { // // } // else { varstart = false; } // tokens.add(token.toString()); // token.setLength(0); // varcount++; if(variable == null) { variable = new Variable(); //variable.setPosition(varcount); variable.setVariableName(var.toString()); var.setLength(0); header.setNext(variable); variable.setParent(header); header = variable; } variables.add(hh); hh = null; i++; } else if(varstart) { if(header == null) { header = new Variable(); header.setPosition(varcount); header.setVariableName(var.toString()); // variables.add(header); var.setLength(0); tokens.add(token.toString()); token.setLength(0); varcount++; hh = header; } varstart = false; variables.add(hh); hh = null; i++; } } } else if (sql.charAt(i) == '-') { if(i + 1 < len ) { if(sql.charAt(i+1) == '>') { if(varstart) { if(!ref_start) { ref_start = true; if(index_start) { index_start = false; indexs = null; var.setLength(0); } else { if(header == null) { header = new Variable(); header.setPosition(varcount); header.setVariableName(var.toString()); // variables.add(header); var.setLength(0); //fixed tokens.add(token.toString()); token.setLength(0); varcount++; hh = header; } else { if(var.length() > 0) { variable = new Variable(); //variable.setPosition(varcount); variable.setVariableName(var.toString()); var.setLength(0); indexs = null; header.setNext(variable); variable.setParent(header); header = variable; } } } } else { if(variable == null)//没有因为索引下标导致引用对象已经创建,则开始创建对象 { variable = new Variable(); //variable.setPosition(varcount); variable.setVariableName(var.toString()); var.setLength(0); indexs = null; header.setNext(variable); variable.setParent(header); header = variable; } else { if(var.length() > 0) { variable = new Variable(); //variable.setPosition(varcount); variable.setVariableName(var.toString()); var.setLength(0); indexs = null; header.setNext(variable); variable.setParent(header); header = variable; } } } index_start = false; indexs = null; } else { token.append("->"); } i++; i++; continue; } else { var.append(sql.charAt(i)); i ++; } } } else { var.append(sql.charAt(i)); i ++; } } else { token.append(sql.charAt(i)); i ++; } } /** * 容错处理: * 情况1.变量没有完全结束(需要反转header对象) * 情况2.后面的字符串没有变量 * a.完全没有变量的相关关键字 * b.有部分变量定义,但是不全 * */ if (token.length() > 0) {//情况2.后面的字符串没有变量 if (var.length() > 0) {// b.有部分变量定义,但是不全,从变量开始的位置恢复token String partvar = sql.substring(varstartposition); token.append("#[").append(partvar); // token.append("#[").append(var); } tokens.add(token.toString()); } else { if (var.length() > 0) {//情况1.变量没有完全结束,从变量开始的位置恢复token // token.append("#[").append(var); String partvar = sql.substring(varstartposition); token.append("#[").append(partvar); int idx = tokens.size() - 1; tokens.set(idx, tokens.get(idx) + token.toString()); // tokens.add(token.toString()); } } if (variables.size() == 0) { return new SQLStruction(sql); } else { SQLStruction itemUrlStruction = new SQLStruction(); itemUrlStruction.setTokens(tokens); itemUrlStruction.setVariables(variables); itemUrlStruction.buildSQL(); return itemUrlStruction; } } /** * 根据引用的维度获取其对应的Pro对象 * @param refid * @return */ public static Object evaluateVariableValue(Variable var,Object bean) { if(bean == null) return null; Object temp = null; PropertieDescription pro = null; List<Index> indexs = null; //if(var.getNext() == null )//不存在引用 indexs = var.getIndexs() ; if(indexs == null || indexs.size() == 0)//直接返回当前数据 { if(var.getNext() == null) return bean; else { temp = bean; var = var.getNext(); } } else//获取数组/map/list或者任意组合中的元素数据 { Class tcls = null; temp = bean; for(Index idx:indexs) { if(idx.getInt_idx() != -1 ) try { tcls = temp.getClass(); if(tcls.isArray()) { temp = Array.get(temp, idx.getInt_idx()); } else // if(List.class.isAssignableFrom(tcls)) { temp = ((List)temp).get(idx.getInt_idx()); } // else // { // // temp = ((Set)temp).get(idx.getInt_idx()); // } } catch (ArrayIndexOutOfBoundsException e) { throw new EvalVariableValueFailedException("获取数组元素失败:数组越界"+temp+"["+idx.getInt_idx()+"]",e); } catch (Throwable e) { throw new EvalVariableValueFailedException("获取数组元素失败:"+temp+"["+idx.getInt_idx()+"]",e); } else try { temp = ((Map)temp).get(idx.getString_idx()); } catch (Throwable e) { throw new EvalVariableValueFailedException("获取Map元素失败:"+temp+"["+idx.getString_idx()+"]",e); } if(temp == null) break; } if(var.getNext() == null ) return temp; else var = var.getNext(); } root: do { if(!(temp instanceof Map)) { pro = ClassUtil.getPropertyDescriptor(temp.getClass(), var.getVariableName()); if(pro == null) throw new EvalVariableValueFailedException("计算变量值失败:class["+bean.getClass().getCanonicalName()+"]没有定义属性["+var.getVariableName()+"]"); try { temp = pro.getValue(temp); } catch (EvalVariableValueFailedException e) { throw e; } catch (IllegalAccessException e) { throw new EvalVariableValueFailedException(e); } catch (InvocationTargetException e) { throw new EvalVariableValueFailedException(e.getTargetException()); } catch (Throwable e) { throw new EvalVariableValueFailedException(e); } } else { temp = ((Map)temp).get(var.getVariableName()); } if(temp == null) break; indexs = var.getIndexs(); if(indexs != null && indexs.size() > 0) { Class tcls = null; for(Index idx:indexs) { if(idx.getInt_idx() != -1 ) try { tcls = temp.getClass(); if(tcls.isArray()) { temp = Array.get(temp, idx.getInt_idx()); } else // if(List.class.isAssignableFrom(tcls)) { temp = ((List)temp).get(idx.getInt_idx()); } } catch (ArrayIndexOutOfBoundsException e) { throw new EvalVariableValueFailedException("获取数组元素失败:数组越界"+temp+"["+idx.getInt_idx()+"]",e); } catch (Throwable e) { throw new EvalVariableValueFailedException("获取数组元素失败:"+temp+"["+idx.getInt_idx()+"]",e); } else try { temp = ((Map)temp).get(idx.getString_idx()); } catch (Throwable e) { throw new EvalVariableValueFailedException("获取Map元素失败:"+temp+"["+idx.getString_idx()+"]",e); } if(temp == null) break root; } } var = var.getNext(); if(var == null) break; }while(true); return temp; } }