浏览 2179 次
锁定老帖子 主题:HQL伪代码解析算法(易扩展)
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-06-10
解析的语法规则: $req{key}$: 典型应用: 1.表示从 当前的requset中 获取数据 key为获取数据的键值. $sen{key}$ 典型应用: 1. $sen{User}$ 表示 从当前session中获取User对象的Id. 2. $sen{User.id}$ 与上面是等价的. 3. $sen{User.userName}$ 表示 从当前session中获取User对象的 用户名 4. $sen{User.field1.field2.fieild...n} 深层属性取值的时候. $date{day,format}$ 典型应用: 1. $date{3}$ 表示获取前三天的时间点 , 默认第二个参数可以不写 默认为:yyyy-MM-dd 2. $date{current}$ 获取当前时期 :默认格式为:yyyy-MM-dd $time{hour,format}$ 典型应用: 1. $time{8}$ 表示获取前8小时的时间点,第二个参数可以不写:默认格式为:yyyy-MM-dd HH:mm:ss 2. $time{current}$ 获取当前时间 :默认格式为:yyyy-MM-dd HH:mm:ss 以下为代码示例: public class DynHqlUtil { /** * hql语句装配 将伪代码转化为可执行代码 * * @param hql * @return * @throws Exception */ public static String hqlLoader(String hql) throws Exception{ DynHqlConfig cfg = new DynHqlConfig(); DynHqlLoader loader = new DynHqlLoader(); return loader.loader(hql, cfg); } public static void main(String[] args) { String hql; try { hql = DynHqlUtil.hqlLoader("from User where xxx = $date{7}$ and bb='k' and kk=$date{current}$"); System.out.println( hql ); } catch (Exception e) { e.printStackTrace(); } } } /***************************************************************************/ public class DynHqlConfig { public static final char BOR = '$'; //$...$ 定义边框 public static final char LEFTSIGN = '{';// 左 括 弧 public static final char RIGHTSIGN = '}';// 右 括 弧 public static final String REQ = "req";//$req{key}$ 定义HttpRequest public static final String SEN = "sen";//$sen{key}$ 定义HttpSession public static final String DATE = "date";//$date{day,format}$ 定义日期 public static final String TIME = "time";//$time{hour}$ 定义时间 public static final String DATE_CURRENT ="current";//定义 本地当前时间 private Map<String,String> mapKey; public DynHqlConfig(){ //此处重定义 伪代码key值 mapKey = new HashMap<String, String>(); mapKey.put("user",Constants.USER_AUTH);//定义取用户的 key值 } public String getKey( String contentKey ) { String key = contentKey.trim().toLowerCase(); if( !mapKey.containsKey(key) ) return key; return mapKey.get(key); } } /*******************************************************************************/ @SuppressWarnings("unused") public class DynHqlLoader { static char[] hex = "0123456789ABCDEF".toCharArray(); private StringBuilder buf ; private DynHqlConfig cfg ; private int startInx = 0; private int endInx = -1; //边框 开始与结束 private boolean borStar = false; private boolean borEnd = false; //大括弧 开始与结束 private boolean bracStar = false; private boolean bracEnd = false; /** * 装配 hql 语句 * @param hql * @param cfg * @return * @throws Exception */ public String loader(String hql , DynHqlConfig cfg) throws Exception{ this.cfg = cfg; this.buf = new StringBuilder(); this.parseHql(hql); return buf.toString(); } /** * 解析 hql * @param hql * @throws Exception */ @SuppressWarnings("static-access") private void parseHql(String hql) throws Exception{ int length = hql.length(); String str = ""; CharacterIterator it = new StringCharacterIterator(hql); boolean sbor = false; boolean ebor = false; int inx = -1; for(char c = it.first(); c != CharacterIterator.DONE; c = it.next()) { endInx++;//实时记录 当前处理的下标 //当遇到第一个 $符号时 开始进入等待下一个对称$ 结束符的出现 否则视为语法错误 原样输出 if( c == cfg.BOR ){ if( sbor && !ebor ) ebor =true; if( !sbor ){ sbor = true; this.appendHql(hql); } } if(sbor && ebor){ sbor = ebor = false ; this.appendFakcCode(hql); } } String h = hql.substring(this.startInx,length); this.buf.append(h); } /** * 拼接 非动态部分 hql * 调整索引下标 * @param hql */ private void appendHql(String hql){ String h = hql.substring(this.startInx,this.endInx); this.buf.append(h); this.startInx = this.endInx; } /** * 处理 动态部分 hql * 调整索引下标 * @param hql */ @SuppressWarnings("static-access") private void appendFakcCode(String hql) throws Exception{ String fcode = hql.substring(this.startInx,this.endInx+1); this.startInx = this.endInx+1; String value = fcode; System.out.println("之前:fcode "+value); if( this.validBracket(fcode) ){ if(fcode.indexOf(cfg.REQ )!=-1){ value = this.request(fcode); }else if(fcode.indexOf(cfg.SEN )!=-1){ value = this.session(fcode); }else if(fcode.indexOf(cfg.DATE )!=-1){ value = this.date(fcode); } else if(fcode.indexOf(cfg.TIME)!=-1){ value = this.time(fcode); } } System.out.println("之后:fcode "+value); this.buf.append(value); } /** * 从 HttpRequest 中取值 */ @SuppressWarnings("static-access") private String request(String fcode){ Object value = fcode; String[] params = null; String key = fcode.substring( fcode.indexOf(cfg.LEFTSIGN)+1,fcode.indexOf(cfg.RIGHTSIGN) ); if(key!=null){ params = (String[])ServletActionContext.getContext().getParameters().get(key.trim()); if( params!=null && params.length>=1 ){ value = params[0]; } } return value.toString(); } /** * 从 HttpSession 中取值 */ @SuppressWarnings("static-access") private String session(String fcode)throws Exception{ String value = fcode; String content = fcode.substring( fcode.indexOf(cfg.LEFTSIGN)+1,fcode.indexOf(cfg.RIGHTSIGN) ); Object obj = null; String key = null; if(content!=null){ //假设 单对象的情况 if( content.indexOf(".")==-1 ){ key = cfg.getKey(content); if( key!=null ) obj = ServletActionContext.getContext().getSession().get( key ); if( obj != null && key != null ){ String methodName = "getId"; if( methodName!=null ) value = (String)obj.getClass().getMethod( methodName ).invoke(obj); } } //假设 对象.属性的情况 if( content.indexOf(".")!=-1 ){ String[] prop = content.split("\\."); key = cfg.getKey(prop[0]); if( key!=null ) obj = ServletActionContext.getContext().getSession().get( key ); if( obj != null && key != null ){ //截取 属性链 (将属性链的第一个去掉) String nextPropLink = content.substring(content.indexOf(".")+1,content.length()); value = this.getParameter(obj,nextPropLink); } } } return value ; } private String getParameter(Object obj , String propLink ) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{ System.out.println( propLink ); String[] fields = propLink.split("\\."); String fieldName = null; String nextPropLink = null; boolean exeRecursion = true; //是否继续执行递归 if( fields.length == 1 ){ exeRecursion = false; fieldName = fields[0]; } if( fields.length > 1 ){ exeRecursion = true; fieldName = propLink.substring(0,propLink.indexOf(".")); nextPropLink = propLink.substring(propLink.indexOf(".")+1,propLink.length()); } BeanInfo info = Introspector.getBeanInfo(obj.getClass()); PropertyDescriptor[] props = info.getPropertyDescriptors(); Object value = obj; for (int i = 0; i < props.length; i++) { PropertyDescriptor prop = props[i]; String name = prop.getName(); if( !name.equals( fieldName ) ){ continue; } Method method = prop.getReadMethod(); value = method.invoke(obj, new Object[0]); if(exeRecursion) return this.getParameter(value, nextPropLink); else break; } return value.toString(); } /** * 获取相对 日期-时间 * * 解析格式 : $date{day,format}$ 第2个参数可不指定 默认为:默认时间格式:yyyy-MM-dd * 默认格式 : $date{current}$ 默认时间格式:yyyy-MM-dd * @param value * @return * @throws Exception */ @SuppressWarnings("static-access") private String date(String fcode) throws Exception{ String content = fcode.substring( fcode.indexOf(cfg.LEFTSIGN)+1,fcode.indexOf(cfg.RIGHTSIGN) ); String value = fcode ; if(content!=null){ String[] args = content.split(","); if(args.length==2){ //获取当前日期 $date{current,yyyy-MM-dd HH:mm:ss}$ if( content.indexOf( cfg.DATE_CURRENT )!=-1 ){ value = this.date(0,args[1]);; } else {//获取指定的相对日期 $date{7,yyyy-MM-dd HH:mm:ss}$ int day = -1; if( (day = this.validNumber(args[0]) )!=-1 ){ value = this.date(day,args[1]); } } } if(args.length==1){ //获取当前日期 $date{current}$ if( content.indexOf( cfg.DATE_CURRENT )!=-1 ){ value = this.date(0,"yyyy-MM-dd");; } else {//获取指定的相对日期 $date{7}$ int day = -1; if( (day = this.validNumber(args[0]) )!=-1 ){ value = this.date(day,"yyyy-MM-dd"); } } } } return value; } /** * 获取 指定的相对时间( 日期-时间 ) * * @param number * @return * @throws Exception */ private String date(int number,String format) throws Exception{ long l = System.currentTimeMillis(); long subDay = (24L*60L*60L*1000L)*(long)number; return DateUtil.getAppointTime( (l-subDay) ,format); } /** * 获取相对 时间(小时) * * 解析格式 : $time{hour,format}$ 第2个参数可不指定 默认为:默认时间格式:yyyy-MM-dd HH:mm:ss * 默认格式 : $time{current}$ 默认时间格式:yyyy-MM-dd HH:mm:ss * @param fcode * @return * @throws Exception */ @SuppressWarnings("static-access") private String time(String fcode)throws Exception{ String content = fcode.substring( fcode.indexOf(cfg.LEFTSIGN)+1,fcode.indexOf(cfg.RIGHTSIGN) ); String value = fcode ; if(content!=null){ String[] args = content.split(","); if(args.length==2){ //获取当前日期 $date{current,yyyy-MM-dd HH:mm:ss}$ if( content.indexOf( cfg.DATE_CURRENT )!=-1 ){ value = this.time(0,args[1]); } else {//获取指定的相对日期 $date{7,yyyy-MM-dd HH:mm:ss}$ int hour = -1; if( (hour = this.validNumber(args[0]) )!=-1 ){ value = this.time(hour,args[1]); } } } if(args.length==1){ //获取当前日期 $date{current}$ if( content.indexOf( cfg.DATE_CURRENT )!=-1 ){ value = this.time(0,"yyyy-MM-dd HH:mm:ss"); } else {//获取指定的相对日期 $date{7}$ int hour = -1; if( (hour = this.validNumber(args[0]) )!=-1 ){ value = this.time(hour,"yyyy-MM-dd HH:mm:ss"); } } } } return value; } /** * 获取 相对时间 (小时) * @param hour * @param format * @return * @throws Exception */ private String time(int hour,String format)throws Exception{ long l = System.currentTimeMillis(); long subHour = (60L*60L*1000L)*(long)hour; return DateUtil.getAppointTime(l-subHour,format); } /** * 验证 括弧的合法性 * @return */ @SuppressWarnings("static-access") private boolean validBracket(String fakcCode){ String fcode = fakcCode; boolean bool = false ; if( (fcode.indexOf(cfg.LEFTSIGN)!=-1) && (fcode.indexOf(cfg.RIGHTSIGN)!=-1)){ bool = true ; } return bool; } /** * 验证是否是 数字字符 * @param strNumber * @return */ private int validNumber(String strNumber){ String strNum = strNumber.trim(); int ascall = -1; if(strNum!=null&&!"".equals(strNum)){ for (int i = 0; i < strNum.length(); i++) { ascall = strNum.charAt(i); if(ascall<'0'|| ascall>'9') return -1; } } return Integer.parseInt( strNum ); } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |