package cn.jcenterhome.service; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import cn.jcenterhome.util.BeanFactory; import cn.jcenterhome.util.Common; import cn.jcenterhome.util.FileHelper; import cn.jcenterhome.util.JavaCenterHome; import cn.jcenterhome.util.Md5Util; import cn.jcenterhome.util.Serializer; public class BlockService { private DataBaseService dataBaseService = (DataBaseService) BeanFactory.getBean("dataBaseService"); @SuppressWarnings("unchecked") public void block_batch(HttpServletRequest request,String param) { Map<String, Object> SBLOCK = new HashMap<String, Object>(); Map<String, Object> sGlobal = (Map<String, Object>) request.getAttribute("sGlobal"); Map<String, Object> sConfig = (Map<String, Object>) request.getAttribute("sConfig"); String cachekey = smd5(param); Map<String,Object> paramarr = parseparameter(param); if(Common.empty(sConfig.get("allowcache"))) { paramarr.put("cachetime", 0); } else { paramarr.put("cachetime", Common.intval((String)paramarr.get("cachetime"))); } if(!Common.empty(paramarr.get("perpage"))) { String pages = request.getParameter("page"); int page = Common.empty(pages)?1:Common.intval(pages); if(page<1) page = 1; if(page>1&&(Integer)paramarr.get("cachetime")>0){ cachekey = smd5(param+page); } } Map caches = new HashMap(); if((Integer)paramarr.get("cachetime")>0) { caches = block_get(cachekey,sGlobal,sConfig); } if(!Common.empty(caches.get("mtime")) && (Integer)sGlobal.get("timestamp")-(Integer)caches.get("mtime") <= (Integer)paramarr.get("cachetime")) { SBLOCK.put((String) paramarr.get("cachename"), caches.get("values")); SBLOCK.put(paramarr.get("cachename")+"_multipage",caches.get("multi")); } else { List<Map<String, Object>> blockarr = new ArrayList<Map<String, Object>>(); Map<String, Object> results = getparamsql(request,paramarr,sGlobal,sConfig); if((Integer)results.get("count")>0) { List<Map<String,Object>> values = dataBaseService.executeQuery((String)results.get("sql")); blockarr = values; } SBLOCK.put((String) paramarr.get("cachename"), blockarr); SBLOCK.put(paramarr.get("cachename")+"_multipage", results.get("multi")); if((Integer)paramarr.get("cachetime")>0) { Map<String,Object> multiMap = new HashMap<String,Object>(); multiMap.put("multipage", results.get("multi")); blockarr.add(multiMap); block_set(cachekey, blockarr,sGlobal,sConfig); } } request.setAttribute("sBlock", SBLOCK); } private String smd5(String str) { return Md5Util.encode(str).substring(8, 16); } private Map<String,Object> parseparameter(String param) { Map<String,Object> paramarr = new HashMap<String,Object>(); String[]sarr = param.split("/"); if(Common.empty(sarr)) return paramarr; int length = sarr.length; for(int i=0; i<length; i=i+2) { if((i+1)<length&&!Common.empty(sarr[i+1])) paramarr.put(sarr[i], Common.urlDecode(sarr[i+1]).replace("/", "").replace("\\", "")); } return paramarr; } @SuppressWarnings("unchecked") private Map<String,Object> getparamsql(HttpServletRequest request,Map<String,Object> paramarr,Map<String, Object> sGlobal,Map<String, Object> sConfig) { String sql = (String) paramarr.get("sql"); Map<String,Object> result = new HashMap<String,Object>(); Matcher m = Pattern.compile("\\[(\\d+)\\]").matcher(sql); if (m.find()) { int time = Common.intval(m.group(1)); int temptime = (Integer) sGlobal.get("timestamp") - time; StringBuffer buffer = new StringBuffer(); m.appendReplacement(buffer, temptime+""); m.appendTail(buffer); sql = buffer.toString(); } paramarr.put("sql", sql); String sqlstring = "SELECT"+sql.trim().replace(";","").replaceAll("(?i)^(select)", ""); if(Common.empty(paramarr.get("perpage"))) { result.put("count", 1); result.put("sql", sqlstring); result.put("multi", ""); return result; } int listcount = 0; String countsql = ""; if(Common.empty(countsql)) { countsql = getcountsql(sqlstring, "SELECT\\s(.+?)\\sFROM\\s(.+?)\\sWHERE\\s(.+?)\\sORDER", 2, 3); } if(Common.empty(countsql)) { countsql = getcountsql(sqlstring, "SELECT\\s(.+?)\\sFROM\\s(.+?)\\sWHERE\\s(.+?)\\sLIMIT", 2, 3); } if(Common.empty(countsql)) { countsql = getcountsql(sqlstring, "SELECT\\s(.+?)\\sFROM\\s(.+?)\\sWHERE\\s(.+?)$", 2, 3); } if(Common.empty(countsql)) { countsql = getcountsql(sqlstring, "SELECT\\s(.+?)\\sFROM\\s(.+?)\\sORDER", 2, -1); } if(Common.empty(countsql)) { countsql = getcountsql(sqlstring, "SELECT\\s(.+?)\\sFROM\\s(.+?)\\sLIMIT", 2, -1); } if(Common.empty(countsql)) { countsql = getcountsql(sqlstring, "SELECT\\s(.+?)\\sFROM\\s(.+?)$", 2, -1); } String multi = ""; if(!Common.empty(countsql)) { listcount = dataBaseService.findRows(countsql); if(listcount>0) { int page = Math.max(Common.intval(request.getParameter("page")),1); int perpage = Common.intval((String)paramarr.get("perpage")); int start = (page-1)*perpage; List<String> urlplus = new ArrayList<String>(); Map<String,String[]> values = (Map<String,String[]>)request.getParameterMap(); Set<String> keys = values.keySet(); for(String key:keys) { if(!"page".equals(key)) urlplus.add(Common.urlEncode(key)+"="+Common.urlEncode(values.get(key)[0])); } String mpurl = request.getRequestURI().replace(".do", ".jsp")+(Common.empty(urlplus)?"":"?"+Common.implode(urlplus, "&")); if(start >= listcount) { page = listcount/perpage; start = (page-1)*perpage;; } int maxPage = (Integer) sConfig.get("maxpage"); multi = Common.multi(request, listcount, perpage, page, maxPage, mpurl, null, null); sqlstring = sqlstring.replaceAll("(?is) LIMIT(.+?)$", ""); sqlstring += " LIMIT "+start+","+paramarr.get("perpage"); } } result.put("count", listcount); result.put("sql", sqlstring); result.put("multi", multi); return result; } private String getcountsql(String sqlstring, String rule, int tablename, int where) { Matcher m = Pattern.compile("(?i)"+rule).matcher(sqlstring); String countsql = ""; if(m.find()){ countsql = "SELECT COUNT(*) FROM "+m.group(tablename)+" WHERE "+(where<0 ? "1" : m.group(where)); } return countsql; } @SuppressWarnings("unchecked") private Map<String,Object> block_get(String cachekey,Map<String,Object>SGLOBAL,Map<String,Object>SCONFIG) { Map<String,Object> caches = new HashMap<String,Object>(); caches.put("mtime", 0); if("file".equals(SCONFIG.get("cachemode"))) { String cachefile = JavaCenterHome.jchRoot+"./data/block_cache/"+getcachedirname(cachekey, "/",SCONFIG)+cachekey+".data"; File file = new File(cachefile); if(file.exists()) { String data = FileHelper.readFile(file); List<Map<String,Object>> blockarr = (List<Map<String,Object>>)Serializer.unserialize(data); Object multipage = blockarr.size()>0 ? blockarr.get(blockarr.size()-1).get("multipage"):""; if(!Common.empty(multipage)) { caches.put("multi", multipage); blockarr.remove(blockarr.size()-1); } else { caches.put("multi", ""); } caches.put("values", blockarr); caches.put("mtime", (int)(file.lastModified()/1000)); } } else { String thetable = JavaCenterHome.getTableName("cache"+getcachedirname(cachekey,"",SCONFIG)); List<Map<String,Object>> resultList = dataBaseService.executeQuery("SELECT * FROM "+thetable+" WHERE cachekey = '"+cachekey+"'"); if(resultList!=null){ if(resultList.size()>0){ Map<String,Object> result = resultList.get(0); List<Map<String,Object>> blockarr = (List<Map<String,Object>>)Serializer.unserialize((String)result.get("value")); Object multipage = blockarr.size()>0 ? blockarr.get(blockarr.size()-1).get("multipage"):""; if(!Common.empty(multipage)) { caches.put("multi", multipage); blockarr.remove(blockarr.size()-1); } else { caches.put("multi", ""); } caches.put("values", blockarr); caches.put("mtime", result.get("mtime")); } }else{ String basetable = JavaCenterHome.getTableName("cache"); List<Map<String,Object>> creatablelist = dataBaseService.executeQuery("SHOW CREATE TABLE "+basetable); Map<String,Object> creattable = creatablelist.get(0); String sql = ((String) creattable.get("Create Table")).replace(basetable,thetable); dataBaseService.executeUpdate(sql); } } return caches; } private String getcachedirname(String cachekey, String ext,Map<String,Object>SCONFIG) { return Common.empty(SCONFIG.get("cachegrade"))?"":cachekey.substring(0, (Integer)SCONFIG.get("cachegrade"))+ext; } private void block_set(String cachekey, List<Map<String,Object>>blockarr,Map<String,Object>sGLOBAL,Map<String,Object>sConfig) { String blockvalue = Serializer.serialize(blockarr); if("file".equals(sConfig.get("cachemode"))){ boolean dircheck = false; String cachedir = JavaCenterHome.jchRoot+"./data/block_cache/"; File dirfile = new File(cachedir); if(!dirfile.isDirectory()){ dirfile.mkdir(); } cachedir += getcachedirname(cachekey,"/",sConfig); dirfile = new File(cachedir); if(!dirfile.isDirectory()){ if(dirfile.mkdir()){ dircheck = true; } }else{ dircheck = true; } if(dircheck){ String cachefile = cachedir+cachekey+".data"; FileHelper.writeFile(cachefile, blockvalue.toString()); } }else{ String thetable = JavaCenterHome.getTableName("cache"+getcachedirname(cachekey,"",sConfig)); dataBaseService.executeUpdate("REPLACE INTO "+thetable+" (cachekey, value, mtime) VALUES ('"+cachekey+"', '"+Common.sAddSlashes(blockvalue)+"', '"+sGLOBAL.get("timestamp")+"')"); } } }