`
roki
  • 浏览: 61874 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

《搜索引擎零距离》IRQL语言的解析

阅读更多
package com.rayeen.spider.vertical.util;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.rayeen.spider.vertical.ParalleIRVirtualMachine;
import com.rayeen.spider.vertical.algorithm.AddFunction;
import com.rayeen.spider.vertical.algorithm.ClearTagFunction;
import com.rayeen.spider.vertical.algorithm.DoubleParameterFunction;
import com.rayeen.spider.vertical.algorithm.EqNullOperator;
import com.rayeen.spider.vertical.algorithm.EqOperator;
import com.rayeen.spider.vertical.algorithm.EqStringOperator;
import com.rayeen.spider.vertical.algorithm.FullUrlFunction;
import com.rayeen.spider.vertical.algorithm.Function;
import com.rayeen.spider.vertical.algorithm.MaxlengthFunction;
import com.rayeen.spider.vertical.algorithm.Operator;
import com.rayeen.spider.vertical.algorithm.RecursiveFunction;
import com.rayeen.spider.vertical.algorithm.ReplaceFunction;
import com.rayeen.spider.vertical.algorithm.SprintfFunction;
import com.rayeen.spider.vertical.algorithm.UneqNullOperator;
import com.rayeen.spider.vertical.algorithm.UneqOperator;
import com.rayeen.spider.vertical.algorithm.UneqStringOperator;
import com.rayeen.spider.vertical.algorithm.UniParameterFunction;
import com.rayeen.spider.vertical.auxiliary.CrawlResultSetCollection;
import com.rayeen.spider.vertical.auxiliary.SemanticException;
import com.rayeen.spider.vertical.auxiliary.TableMerge;
import com.rayeen.spider.vertical.constant.ArgumentType;
import com.rayeen.spider.vertical.constant.ConfConstant;
import com.rayeen.spider.vertical.constant.ErrorType;
import com.rayeen.spider.vertical.constant.FunctionConstant;

public class ResutTree {

	static final Logger LOG = Logger.getLogger(ResutTree.class);

	static Map<String, Function> FunctionNameMap = new ConcurrentHashMap<String, Function>();

	// 单参数的函数
	static Set<String> uniParameterFunction = new HashSet<String>();

	//
	static Set<String> doubleParameterFunction = new HashSet<String>();

	static {
		uniParameterFunction.add(FunctionConstant.FULL_URL);
		uniParameterFunction.add(FunctionConstant.CLEAR_TAG);

		doubleParameterFunction.add(FunctionConstant.MAX_LENGTH);
		doubleParameterFunction.add(FunctionConstant.ADD);

	}

	static Function getFunctionInstance(String func) {

		Class cls = FunctionNameMap.get(func).getClass();
		Function f = null;
		try {
			f = (Function) cls.newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return f;
	}

	// 考虑f(..) showF:toByte情况
	static Pattern FUNC_PATTERN = Pattern
			.compile("(\\w+)\\s*\\((.+?)\\)\\s+(\\w+(:\\w+)?)");

	Map<String, Function> fieldFunctionMap = new ConcurrentHashMap<String, Function>();

	Map<String, Function> showFieldFunctionMap = new ConcurrentHashMap<String, Function>();

	static Map<String, Operator> operators = new LinkedHashMap<String, Operator>();
	static {
		operators.put("!=", new UneqOperator());
		operators.put("=", new EqOperator());
		operators.put("is", new EqNullOperator());
		operators.put("not", new UneqNullOperator());

		FunctionNameMap.put(FunctionConstant.FULL_URL, new FullUrlFunction());
		FunctionNameMap.put(FunctionConstant.SPRINGTF, new SprintfFunction());
		FunctionNameMap
				.put(FunctionConstant.RECURSIVE, new RecursiveFunction());
		FunctionNameMap.put(FunctionConstant.ADD, new AddFunction());
		FunctionNameMap.put(FunctionConstant.REPLACE, new ReplaceFunction());
		FunctionNameMap.put(FunctionConstant.CLEAR_TAG, new ClearTagFunction());
		FunctionNameMap.put(FunctionConstant.MAX_LENGTH,
				new MaxlengthFunction());

	}

	public ResutTree(URL rootUrl,
			Map<String, Map<String, String>> hierarchyResult,
			CrawlResultSetCollection crawlRSC) {

		this.rootUrl = rootUrl;
		this.hierarchyResult = hierarchyResult;
		this.crawlRSC = crawlRSC;
		/**
		 * curUniResultTableMap里的数据的key以"tableName->extractName"构成
		 */
	}

	static void error(String str) throws SemanticException {
		LOG.error(str);
		throw new SemanticException(str);
	}

	static void warn(String str) {
		LOG.error(str);
	}

	URL rootUrl;

	Map<String, Map<String, String>> hierarchyResult = new HashMap<String, Map<String, String>>();

	CrawlResultSetCollection crawlRSC;

	Map<String, TableMerge> mergeMap = new ConcurrentHashMap();

	class Pfk {
		String p;// 表名

		String f;// 内部字段

		String k;// 表示字段

		public Pfk(String p, String f, String k) {
			super();
			this.p = p;
			this.f = f;
			this.k = k;

			if (StringUtils.isEmpty(k)) {
				this.k = f;
			}
		}

		public String toString() {
			return p + ":" + f + ":" + k;
		}
	}

	class Pkpk {

		Operator operator;

		ArgumentType argumentType;

		List<String> argList;

		/**
		 * 不同argmentType ,和operator会对argList做不同的处理
		 * 
		 */
		public Pkpk(ArgumentType argmentType, Operator operator,
				List<String> argList) {
			this.argumentType = argmentType;
			this.operator = operator;
			this.argList = argList;
		}

		public String toString() {
			return argumentType + ":" + operator + ":" + argList.toString();
		}

		public List<String> getArgList() {
			return argList;
		}

		public void setArgList(List<String> argList) {
			this.argList = argList;
		}

		public ArgumentType getArgmentType() {
			return argumentType;
		}

		public void setArgmentType(ArgumentType argmentType) {
			this.argumentType = argmentType;
		}

		public Operator getOperator() {
			return operator;
		}

		public void setOperator(Operator operator) {
			this.operator = operator;
		}

	}

	private List<Map> filterFinalResult(List<Map<String, String>> mainRows,
			List<Pfk> pfkList, ArrayList<Pfk> hierarchyPfkList,
			List<Pkpk> pkpkList) throws SemanticException {

		Map<String, String> fieldMap = new HashMap<String, String>();
		for (Pfk tmp : pfkList) {
			if (fieldMap.containsKey(tmp.k)) {
				error("duplicate show key :" + tmp.k);
			} else {
				fieldMap.put(tmp.p + "." + tmp.f, tmp.k);
			}
		}

		for (Pfk tmp : hierarchyPfkList) {
			if (fieldMap.containsKey(tmp.k)) {
				error("duplicate show key :" + tmp.k);
			} else {
				fieldMap.put(tmp.p + "." + tmp.f, tmp.k);
			}
		}

		List<Map> resultList = new ArrayList<Map>();
		for (Map<String, String> res : mainRows) {

			boolean fit = true;
			for (Pkpk p : pkpkList) {

				if (p.getArgmentType() == ArgumentType.ONE) {
					String p1 = p.getArgList().get(0);
					String f1 = p.getArgList().get(1);
					if (!p.getOperator().operator(res.get(p1 + "." + f1))
							.equals(ConfConstant.TRUE)) {
						fit = false;
						break;
					}
				}

				if (p.getArgmentType() == ArgumentType.TWO) {
					String p1 = p.getArgList().get(0);
					String f1 = p.getArgList().get(1);

					String p2 = p.getArgList().get(2);
					String f2 = p.getArgList().get(3);

					if (!p.getOperator().operator(res.get(p1 + "." + f1),
							res.get(p2 + "." + f2)).equals(ConfConstant.TRUE)) {
						fit = false;
						break;
					}
				}

			}


			if (fit) {

				Map<String, String> tmpMap = new HashMap<String, String>();
				for (String key : res.keySet()) {
					if (fieldMap.containsKey(key) &&  !fieldMap.get(key).endsWith(":FUNCTION")) {

						String value = res.get(key);

						tmpMap.put(fieldMap.get(key), value);
					}
				}

				// 添加由function产生的字段
				for (String key : showFieldFunctionMap.keySet()) {
					Function func = showFieldFunctionMap.get(key);
					String fieldValue = "";

					if (func instanceof FullUrlFunction) {
						String field = ((FullUrlFunction) func).getField();
						fieldValue = res.get(field);
						// tmpMap.remove(ParseUtils.parseFieldShowValue(field));
						fieldValue = func.operator(new Object[] { rootUrl,
								fieldValue });

					} else if (func instanceof SprintfFunction) {
						SprintfFunction sf = (SprintfFunction) func;
						List<String> fields = sf.getFields();
						List<String> args = new ArrayList<String>();
						args.add(sf.getFormat());
						for (String f : fields) {
							args.add(res.get(f));
							// tmpMap.remove(ParseUtils.parseFieldShowValue(f));
						}
						fieldValue = sf.operator(args.toArray());

					} else if (func instanceof ReplaceFunction) {
						ReplaceFunction rpf = (ReplaceFunction) func;
						String field = res.get(rpf.getField());
						fieldValue = rpf.operator(new Object[] { field,
								rpf.getPatternStr(), rpf.getReplaceStr() });

						// tmpMap.remove(ParseUtils.parseFieldShowValue(addf.getField()));
					} else if (func instanceof ClearTagFunction) {
						ClearTagFunction ctf = (ClearTagFunction) func;
						String value = res.get(ctf.getField());
						fieldValue = ctf.operator(new Object[] { value });

						// tmpMap.remove(ParseUtils.parseFieldShowValue(addf.getField()));
					} else if (func instanceof DoubleParameterFunction) {
						// 通用些的放在后面尝试匹配
						// 单参数的,普通形式的函数,包括Add,Maxlength
						String field = ((DoubleParameterFunction) func)
								.getField();
						String parameter = ((DoubleParameterFunction) func)
								.getParameter();
						fieldValue = res.get(field);
						fieldValue = func.operator(new Object[] { fieldValue });

					} else if (func instanceof RecursiveFunction) {

						RecursiveFunction rf = (RecursiveFunction) func;
						List<String> args = new ArrayList<String>();

						String functions = rf.getFunctions();
						args.add(functions);

						String[] params = rf.getParams();

						for (String f : params) {
							// 如果是字段名,则计算字段的值
							if (!f.startsWith("\"")) {
								args.add(res.get(f));
							} else { // 否则,直接添加这个函数
								args.add(ParseUtils.parseStrContent(f));
							}
							// tmpMap.remove(ParseUtils.parseFieldShowValue(f));
						}
						fieldValue = rf.operator(args.toArray());

					}

					// fieldValue=showFieldFunctionMap.get(key).operator(new
					// Object[]{value});
					tmpMap.put(key, fieldValue);
				}

				resultList.add(tmpMap);
			}

		}
		return resultList;

	}

	/**
	 * get main row and call "filterFinalResult"
	 * 
	 * @param pageNameMap
	 * @param pfkList
	 * @param pkpkList
	 * @return
	 * @throws SemanticException
	 */
	@SuppressWarnings("unchecked")
	private List<Map> getFinalResult(Map<String, String> pageNameMap,
			List<Pfk> pfkList, ArrayList<Pfk> hierarchyPfkList,
			List<Pkpk> pkpkList) throws SemanticException {

		long threadId = Thread.currentThread().getId();

		// 把表名排序
		Collections.sort(pfkList, new Comparator() {

			public int compare(Object o1, Object o2) {
				Pfk p1 = (Pfk) o1;
				Pfk p2 = (Pfk) o2;
				return p1.p.compareToIgnoreCase(p2.p);
			}

		});
		//

		// 某个表在显示中涉及的式子
		Map<String, Set<String>> pkfMap = new HashMap();
		for (Pfk tmp : pfkList) {
			if (!pkfMap.containsKey(tmp.p)) {
				Set<String> set = new HashSet();
				set.add(tmp.f);
				pkfMap.put(tmp.p, set);
			} else {
				pkfMap.get(tmp.p).add(tmp.f);
			}

		}

		Map<String, Set<String>> hierarchyPkfMap = new HashMap();
		for (Pfk tmp : hierarchyPfkList) {
			if (!hierarchyPkfMap.containsKey(tmp.p)) {
				Set<String> set = new HashSet();
				set.add(tmp.f);
				hierarchyPkfMap.put(tmp.p, set);
			} else {
				hierarchyPkfMap.get(tmp.p).add(tmp.f);
			}

		}

		// 这个Map记录了某个数据表在IRQL中的投影字段中涉及的字段名。
		// 投影字段可能是空的。
		Map<String, Set<String>> pkpkMap = new HashMap();

		for (Pkpk tmp : pkpkList) {

			if (tmp.getArgmentType() == ArgumentType.ONE) {
				if (tmp.getArgList().size() >= 2) {
					String page = tmp.getArgList().get(0);
					String field = tmp.getArgList().get(1);

					if (!pkpkMap.containsKey(page)) {
						Set<String> set = new HashSet();
						pkpkMap.put(page, set);
					}
					// 先添加set
					// 再往set里加东西
					// 前提是表名在显示列里出现过了
					if (pkfMap.containsKey(page)) {
						pkpkMap.get(page).add(field);
					}
				}

			}

			if (tmp.getArgmentType() == ArgumentType.TWO) {
				if (tmp.getArgList().size() == 2) {
					String page = tmp.getArgList().get(2);
					String field = tmp.getArgList().get(3);

					if (!pkpkMap.containsKey(page)) {
						Set<String> set = new HashSet();
						pkpkMap.put(page, set);
					}

					if (pkfMap.containsKey(page)) {
						pkpkMap.get(page).add(field);
					}
				}
			}

		}

		String curTableName = "";
		String exTableName = "";
		// 以select P1.bcname bcname,P2.scame scame,P3.songname
		// songname,P3.downlink downlink"
		// 为主线,从左到右做连接

		List<Map<String, String>> mainRows = new ArrayList();

		for (Pfk pfk : pfkList) {

			// 一条临时结果
			// 获取表名

			if (!pageNameMap.containsKey(pfk.p)) {
				ParalleIRVirtualMachine.error("invalid pagename:" + pfk.p,
						ErrorType.SEMANTIC);
			}
			String tableName = pageNameMap.get(pfk.p);

			if (mergeMap.containsKey(tableName)) {
				continue;
			}

			if (null == tableName) {
				ParalleIRVirtualMachine.error("invalid page alias" + pfk.p,
						ErrorType.SEMANTIC);
			}

			curTableName = tableName;

			List<Map<String, String>> rows = new ArrayList();

			// 数据不在共享表中的话,到独立表中去找
			// "下载页->down"这种表明肯定在shareTable中找不到
			// 更好的写法应该是 if(tableName.contains("->"))
			if (crawlRSC.getGlobalShareResultTableMap(tableName).size() == 0) {

				// 页名->规则名
				String[] prPair = tableName.split("->");
				if (prPair.length == 2) {

					String pageName = prPair[0];
					String ruleName = prPair[1];
					// 页间总表集合和页内独立表集合中都没有那个表
					if (crawlRSC.getGlobalUniResultTableMap(pageName, ruleName)
							.size() == 0) {
						warn("Thread-" + threadId
								+ ":invalid uniTable pagename:" + pageName
								+ "->" + ruleName);
						continue;
					} else {

						rows = crawlRSC.getGlobalUniResultTableMap(pageName,
								ruleName);
					}
				} else {
					warn("invalid pagename:" + tableName + " or match failed");
				}
			} else {
				// 数据在共享表中
				rows = crawlRSC.getGlobalShareResultTableMap(tableName);
			}

			if (rows.size() == 0) {
				break;
			}

			// 开始一张新表的处理
			if (StringUtils.isNotEmpty(exTableName)
					&& !StringUtils.equalsIgnoreCase(curTableName, exTableName)) {

				// 把mainRows和rows连接
				List<Map<String, String>> tmpRows = new ArrayList();
				for (Map<String, String> result : mainRows) {
					// 新建一条记录,然后把左面表+右面的结果 放进临时表

					for (Map<String, String> map : rows) {
						Map<String, String> tpMap = new HashMap();
						tpMap.putAll(result);
						
						//判断一下pfk.k里是否有 :toByte,如果有的话需要去掉:toByte,才能取到值
						String key=pfk.k;
						if(pfk.k.endsWith(ConfConstant.TO_BYTE)){
							int ix = pfk.k.lastIndexOf(ConfConstant.TO_BYTE);
							key=	key.substring(0, ix);
						}
						
						tpMap.put(pfk.p + "." + pfk.f, map.get(key));

						// 投影字段可能是空的
						if (pkpkMap.containsKey(pfk.p)) {
							Set<String> ext = pkpkMap.get(pfk.p);
							for (String f : ext) {
								tpMap.put(pfk.p + "." + f, map.get(f));
							}
						}
						// 临时表中添加一行
						tmpRows.add(tpMap);
					}

				}

				mainRows = tmpRows;// 笛卡尔积完成

			} else {// 继续放同一张表的数据

				if (StringUtils.isEmpty(exTableName)) {

					for (Map<String, String> map : rows) {
						Map<String, String> tpMap = new HashMap();
						
						String fld=pfk.f;
						if(fld.endsWith(ConfConstant.FUNCTOIN_POSTFIX)){
							fld=fld.substring(0,fld.length()-ConfConstant.FUNCTOIN_POSTFIX.length()  );
						}
						
						tpMap.put(pfk.p + "." + pfk.f, map.get(fld));

						// 投影字段可能是空的
						if (pkpkMap.containsKey(pfk.p)) {
							Set<String> ext = pkpkMap.get(pfk.p);
							for (String f : ext) {
								tpMap.put(pfk.p + "." + f, map.get(f));
							}
						}

						mainRows.add(tpMap);
					}
				} else {

					for (int i = 0; i < mainRows.size(); i += rows.size()) {
						
						
						//遇到有":FUNCTION"的情况下,需要处理一下
						String fld=pfk.f;
						if(fld.endsWith(ConfConstant.FUNCTOIN_POSTFIX)){
							fld=fld.substring(0,fld.length()-ConfConstant.FUNCTOIN_POSTFIX.length()  );
						}
						

						String pf = pfk.p + "." + pfk.f;
						for (int j = 0; j < rows.size(); j++) {
							mainRows.get(i + j).put(pf, rows.get(j).get(fld));

							if (pkpkMap.containsKey(pfk.p)) {
								Set<String> ext = pkpkMap.get(pfk.p);
								for (String f : ext) {
									mainRows.get(i + j).put(pfk.p + "." + f,
											rows.get(j).get(f));
								}
							}
						}
					}

				}

			}

			exTableName = tableName;

		}

		// 可以在所有表处理完之后,再处理融合的表
		for (String targetKey : mergeMap.keySet()) {

			String p = "";
			for (String pkey : pageNameMap.keySet()) {
				if (pageNameMap.get(pkey).equals(targetKey)) {
					p = pkey;
					break;
				}
			}
			if (StringUtils.isEmpty(p)) {
				ParalleIRVirtualMachine.error(
						"invalid page alias:" + targetKey, ErrorType.SEMANTIC);
			}

			if (StringUtils.isEmpty(targetKey))
				continue;

			TableMerge merge = mergeMap.get(targetKey);
			Set<String> srcTbls = merge.getMergedTable();

			List<Map<String, String>> mainMergeRows = new ArrayList();

			// 先添加一条空数据
			// mainRow.add(new HashMap());

			for (String tableName : srcTbls) {

				List<Map<String, String>> rows = new ArrayList();

				String[] prPair = tableName.split("->");

				if (prPair.length == 2) { // 是独立表
					String pageName = prPair[0].trim();
					String ruleName = prPair[1].trim();

					if (crawlRSC.getGlobalUniResultTableMap(pageName, ruleName)
							.size() == 0) {
						warn("Thread-" + threadId
								+ ":invalid uniTable pagename:" + pageName
								+ "->" + ruleName);
						continue;
					} else {
						rows = crawlRSC.getGlobalUniResultTableMap(pageName,
								ruleName);

						if (mainRows.size() == 0) {

							List<Map<String, String>> tmpRows = new ArrayList();

							for (Map<String, String> row : rows) {
								Map tmpMap = new HashMap();
								for (String columName : row.keySet()) {
									tmpMap.put(p + "." + columName, row
											.get(columName));
								}
								tmpRows.add(tmpMap);
							}
							mainRows = tmpRows;
						} else {

							// 2x2=>4
							List<Map<String, String>> tmpRows = new ArrayList();

							for (Map<String, String> mainColumn : mainRows) {

								for (Map<String, String> row : rows) {
									Map<String, String> tmpMap = new HashMap();
									for (String columName : row.keySet()) {
										tmpMap.put(p + "." + columName, row
												.get(columName));
									}
									tmpMap.putAll(mainColumn);
									tmpRows.add(tmpMap);
								}
							}
							mainRows = tmpRows;
						}

						// }
					}
				} else {// 是共享表

					String pageName = tableName.trim();
					if (crawlRSC.getGlobalShareResultTableMap(pageName).size() == 0) {
						warn("Thread-" + threadId + ":invalid  pagename:"
								+ pageName);
						continue;
					} else {
						rows = crawlRSC.getGlobalShareResultTableMap(pageName);

						if (mainRows.size() == 0) {
							mainRows = rows;
						} else {
							for (Map<String, String> mainColumn : mainRows) {
								for (Map<String, String> column : rows) {
									mainColumn.putAll(column);
								}
							}
						}

					}
				}
			}

		}

		// 直接从hierarchyPfkList引用数据
		for (Pfk pfk : hierarchyPfkList) {

			// 获取表名
			String tableName = pageNameMap.get(pfk.p);

			curTableName = tableName;

			if (!hierarchyResult.containsKey(tableName)) {
				String err = "invalid hierarchy tableName:" + tableName;
				err += ",\n if u want to specify a  hierarchy tableName, u needn't to write the matchName";
				err += ",\n because only one matchName can be used as a hierarchyTable";
				error(err);
				continue;
			}
			Map<String, String> row = hierarchyResult.get(tableName);

			// 即使是在继承表里,字段名也是用“.”连起来, 为了统一起见
			// 因此,在函数型字段的处理中,需要注意这个问题
			for (int i = 0; i < mainRows.size(); i++) {
				String pf = pfk.p + "." + pfk.f;
				mainRows.get(i).put(pf, row.get(pfk.f));
			}

		}

		return filterFinalResult(mainRows, pfkList, hierarchyPfkList, pkpkList);

	}

	public List<Map> getMapResult(String irql) throws SemanticException {

		int pm = irql.indexOf(";");
		if (-1 == pm) {
			String err = "invalid IRQL format:" + irql;
			err += "\nhave u forget to put ';' after Page Define?";
			ParalleIRVirtualMachine.error(err, ErrorType.SEMANTIC);
		}
		String pageStr = irql.substring(0, pm);

		Map<String, String> pageNameMap = new HashMap<String, String>();

		String[] fields = pageStr.split(",");
		for (String field : fields) {
			String[] kv = field.split(":");
			if (kv.length == 2) {
				pageNameMap.put(kv[1].trim(), kv[0].trim());
			} else {
				error("error pageMap description:" + field);
			}
		}

		String prefix = "";
		String postfix = "";
		int w = irql.indexOf("where");
		if (w != -1) {
			prefix = irql.substring(pm + 1, w).trim();
			postfix = irql.substring(w);
		} else {
			prefix = irql;
		}

		int s = prefix.indexOf("select");
		if (s == -1) {
			ParalleIRVirtualMachine.error("miss 'select'", ErrorType.GRAMMER);
		}
		s = s + "select".length();

		String fieldStr = prefix.substring(s).trim();

		Set<String> functionalFields = new HashSet();

		Matcher m = FUNC_PATTERN.matcher(fieldStr);

		boolean found = false;
		int last = 0;
		while (m.find(last)) {

			found = true;

			last = m.end();

			String field = m.group(0);
			
			
			

			String functionName = m.group(1);
			Function fun = FunctionNameMap.get(functionName);

			String showField = m.group(3);

			if (null == fun) {
				error("unexisting function anme :" + functionName);
			}

			// 一个参数的函数
			if (uniParameterFunction.contains(functionName)) {
				UniParameterFunction func = (UniParameterFunction) getFunctionInstance(functionName);

				field = m.group(2);

				// 避免忘记写 别名
				if (field.contains(",") || field.contains(")")) {
					error("invalid Uniunction format");
				}
				String tableFieldKey = field.replace("->", ".");
				
//				加上":FUNCTION"后缀
				tableFieldKey=tableFieldKey+ConfConstant.FUNCTOIN_POSTFIX;
				
				func.setField(tableFieldKey);
				
				

				
				functionalFields.add(field);
				showFieldFunctionMap.put(showField, func);
			}

			if (doubleParameterFunction.contains(functionName)) {
				DoubleParameterFunction func = (DoubleParameterFunction) getFunctionInstance(functionName);

				String[] args = m.group(2).split(",");

				func.setParameter(ParseUtils.parseStrContent(args[1].trim()));
				if (args.length != 2) {
					error("invalid DoubleParameterFunction format");
				}
				String tableFieldKey = args[0].replace("->", ".");
				
//				加上":FUNCTION"后缀
				tableFieldKey=tableFieldKey+ConfConstant.FUNCTOIN_POSTFIX;
				
				
				func.setField(tableFieldKey);
				functionalFields.add(args[0]);// 必须把这个字段加入“结果集中出现的字段”,不能漏掉
				showFieldFunctionMap.put(showField, func);

			}

			// 3个参数的函数
			if (functionName.equals(FunctionConstant.REPLACE)) {
				ReplaceFunction rpf = new ReplaceFunction();
				String[] args = m.group(2).split(",");
				if (args.length != 3) {
					error("invalid parameter for replace function");
				}

				String tableFieldKey = args[0].replace("->", ".");
				
//				加上":FUNCTION"后缀
				tableFieldKey=tableFieldKey+ConfConstant.FUNCTOIN_POSTFIX;
				
				rpf.setField(tableFieldKey);

				String patternStr = args[1].replace("\\\"", "");
				String replaceStr = args[2].replace("\\\"", "");
				rpf.setPatternStr(patternStr);
				rpf.setReplaceStr(replaceStr);

				functionalFields.add(tableFieldKey);

				showFieldFunctionMap.put(showField, rpf);
			}

			// N个参数的函数
			if (functionName.equals(FunctionConstant.SPRINGTF)) {
				SprintfFunction spf = new SprintfFunction();
				String[] args = m.group(2).split(",");

				spf.setFormat(ParseUtils.parseStrContent(args[0].trim()));
				ArrayList<String> spFields = new ArrayList();
				for (int i = 1; i < args.length; i++) {
					// 这个字段名需要把共享表,独立表,继承表三种形式统一起来
					String tableFieldKey = args[i].replace("->", ".");
					
					
//					加上":FUNCTION"后缀
					tableFieldKey=tableFieldKey+ConfConstant.FUNCTOIN_POSTFIX;
					
					spFields.add(tableFieldKey);
					functionalFields.add(args[i]);
				}
				spf.setFields(spFields.toArray(new String[0]));
				showFieldFunctionMap.put(showField, spf);
			}

			// 逆波兰式 递归函数
			if (functionName.equals(FunctionConstant.RECURSIVE)) {
				RecursiveFunction rf = new RecursiveFunction();
				String[] args = m.group(2).split(",");

				rf.setFunctions(ParseUtils.parseStrContent(args[0].trim()));

				List<String> params = new ArrayList();
				for (int i = 1; i < args.length; i++) {
					// 这个字段名需要把共享表,独立表,继承表三种形式统一起来

					if (!args[i].trim().startsWith("\"")) {
						String tableFieldKey = args[i].replace("->", ".");
						
//						加上":FUNCTION"后缀
						tableFieldKey=tableFieldKey+ConfConstant.FUNCTOIN_POSTFIX;
						
						functionalFields.add(tableFieldKey);
						params.add(args[i]);
					} else {
						params.add(args[i]);
					}
				}
				rf.setParams(params.toArray(new String[0]));
				showFieldFunctionMap.put(showField, rf);
			}

		}

		if (found) {
			fieldStr = m.replaceAll("");
		}

		// 把fieldStr里的函数型字段找出来,换成空
		ArrayList<Pfk> pfk = new ArrayList<Pfk>();

		ArrayList<Pfk> hierarchyPfk = new ArrayList<Pfk>();

		fields = fieldStr.split(",");

		Set<String> metNames = new HashSet<String>();

		// 函数型字段和普通字段分开处理。。。函数型字段没有别名
		//给函数型字段的k值加上 “:FUNCTION”后缀,就不会把单独字段的值显示值冲掉了
		//比如 cleartag(P.f) f, P.f f2,这时候f和f2这两个字段就能分别取道正确的值了
		//f值必须是	“:FUNCTION”结尾,因为filterFinalResult函数中的if (fieldMap.containsKey(key) &&  !fieldMap.get(key).endsWith(":FUNCTION")) {
		//这段里会需要判断是否“:FUNCTION”结尾
		//而k值必须“:FUNCTION”结尾,否则会冲掉P.f的showField
		//fieldMap={"P.f:FUNCTION"=>"f1","P.f"=>"f2"}
		//只要"P.f"=>"f2这条不要被冲掉就可以了,而两个function相互冲掉是没关系的
		for (String field : functionalFields) {
			field = field.trim();

			// 链接语义的数据集
			if (field.indexOf("->") > 0) {
				String[] pf = field.trim().split("->");
				if (pf.length == 2) {
					String f = ParseUtils.getRealFieldName(pf[1]);
					//hierarchyPfk.add(new Pfk(pf[0].trim(), f, f));
					hierarchyPfk.add(new Pfk(pf[0].trim(), f+ConfConstant.FUNCTOIN_POSTFIX, f));
				} else {
					error("error prefix pf:" + field);
				}
			} else {

				String[] pf = field.trim().split("\\.");

				if (pf.length == 2) {
					String f = ParseUtils.getRealFieldName(pf[1]);
					//pfk.add(new Pfk(pf[0].trim(), f, f));
					pfk.add(new Pfk(pf[0].trim(), f+ConfConstant.FUNCTOIN_POSTFIX, f));
				} else {
					error("error prefix pf:" + field);
				}
			}
		}

		for (String field : fields) {

			if (StringUtils.isBlank(field))
				continue;

			field = field.trim();

			String[] kv = field.trim().split("\\s+");

			if (kv.length == 2) {
				// 显示字段重复性校验
				if (!metNames.contains(kv[1].trim())) {
					metNames.add(kv[1].trim());
				} else {
					error("duplicate show field:" + kv[1]);
				}

				// 链接语义的数据集 select P.songName songName,P->downlink downlink;
				if (kv[0].indexOf("->") > 0) {
					String[] pf = kv[0].split("->");
					if (pf.length == 2) {

						hierarchyPfk.add(new Pfk(pf[0].trim(), pf[1].trim(),
								kv[1].trim()));
					} else {
						error("error prefix pf:" + kv[0]);
					}
				} else {

					String[] pf = kv[0].trim().split("\\.");
					if (pf.length == 2) {

						pfk.add(new Pfk(pf[0].trim(), pf[1].trim(), kv[1]
								.trim()));
					} else {
						error("error prefix pf:" + kv[0]);
					}
				}

			} else if (kv.length == 1) { // select P.songName,P->downlink;
				// 链接语义的数据集
				if (kv[0].indexOf("->") > 0) {
					String[] pf = kv[0].trim().split("->");

					if (pf.length == 2) {
						String f = ParseUtils.getRealFieldName(pf[1]);
						// 显示字段重复性校验
						if (!metNames.contains(f)) {
							metNames.add(f);
						} else {
							error("duplicate show field:" + f);
						}

						metNames.add(pf[1]);
						hierarchyPfk.add(new Pfk(pf[0].trim(), f, f));

					} else {
						error("error prefix pf:" + kv[0]);
					}

				} else {

					String[] pf = kv[0].trim().split("\\.");

					if (pf.length == 2) {

						String f = ParseUtils.getRealFieldName(pf[1]);

						if (!metNames.contains(f)) {
							metNames.add(f);
						} else {
							error("duplicate show field:" + f);
						}
						pfk.add(new Pfk(pf[0].trim(), f, pf[1].trim()));
					} else {
						error("error prefix pf:" + kv[0]);
					}
				}
			} else {
				StringBuffer fieldsError = new StringBuffer();
				for (String f : kv) {
					fieldsError.append(f);
				}
				error("error fields description:" + fieldsError);
			}
		}// end foreach fields

		w = postfix.indexOf("where");
		if (w != -1) {
			fieldStr = postfix.substring(w + "where".length()).trim();
		} else {
			fieldStr = "";
		}

		ArrayList<Pkpk> pkpk = new ArrayList();

		fields = new String[0];

		// 投影条件
		if (StringUtils.isNotEmpty(fieldStr)) {
			fields = fieldStr.split("and");
		}

		for (String field : fields) {

			field = field.trim();
			String optag = "=";
			// 算符
			Operator operator = null;

			// 分析表达式中的算符
			for (String op : operators.keySet()) {
				if (field.contains(op)) {
					optag = op;
					operator = operators.get(op);
					break;
				}
			}

			// P1.F1=P2.F2, P1.F1=NULL
			String[] kv = field.split(optag);
			if (kv.length == 2) {// 当前只支持以上两种语法,因此这条应该肯定成立

				String tableKey = kv[0].trim().replace("->", ".");

				String[] pf = tableKey.split("\\.");

				String p1 = null, f1 = null, p2 = null, f2 = null;
				if (pf.length == 2) {
					p1 = pf[0].trim();
					f1 = pf[1].trim();
				} else {
					error("error post pf");
				}

				List args = new CopyOnWriteArrayList();

				String targetTableKey = kv[1].trim();
				// 非空的过滤条件,单参数
				if (targetTableKey.equals(ConfConstant.NULL)) {

					args.addAll(Arrays.asList(new String[] { p1, f1 }));
					Pkpk cmpNullOP = new Pkpk(ArgumentType.ONE, operator, args);
					pkpk.add(cmpNullOP);
				} else if (targetTableKey.startsWith("\"")
						&& targetTableKey.endsWith("\"")) {
					String str = targetTableKey.substring(1, targetTableKey
							.length() - 1);

					// 不等于或者等于字符串
					if (operator instanceof UneqOperator) {
						operator = new UneqStringOperator(str);
					} else {
						operator = new EqStringOperator(str);
					}
					args.addAll(Arrays.asList(new String[] { p1, f1, str }));
					Pkpk cmpStrOP = new Pkpk(ArgumentType.ONE, operator, args);
					pkpk.add(cmpStrOP);

				} else {

					pf = kv[1].trim().split("\\.");
					if (pf.length == 2) {
						p2 = pf[0].trim();
						f2 = pf[1].trim();
						args.addAll(Arrays
								.asList(new String[] { p1, f1, p2, f2 }));
					} else {
						error("error post pf");
					}
					Pkpk cmpOP = new Pkpk(ArgumentType.TWO, operator, args);
					pkpk.add(cmpOP);
				}

			} else {
				error("error fields description");
			}
		}

		return getFinalResult(pageNameMap, pfk, hierarchyPfk, pkpk);

	}

	public static void main(String[] argv) {

		// 构造源数据
		Map<String, List<Map<String, String>>> pageMap = new HashMap();

		// P1的数据
		List<Map<String, String>> page = new ArrayList();
		HashMap map = new HashMap();
		map.put("bcid", "v_bcid");
		map.put("bcname", "v_bcname");
		page.add(map);

		map = new HashMap();
		map.put("bcid", "v_bcid1");
		map.put("bcname", "v_bcname1");
		page.add(map);

		pageMap.put("pagename1", page);

		// P2的数据
		page = new ArrayList();
		map = new HashMap();
		map.put("bcid", "v_bcid");
		map.put("scid", "v_sci");
		map.put("scname", "v_scname");
		page.add(map);

		map = new HashMap();
		map.put("bcid", "v_bcid1");
		map.put("scid", "v_sci1");
		map.put("scname", "v_scname1");

		page.add(map);

		map = new HashMap();
		map.put("bcid", "v_bcid1");
		map.put("scid", "v_sci2");
		map.put("scname", "v_scname2");
		page.add(map);
		pageMap.put("pagename2", page);

		// P3的数据
		page = new ArrayList();
		map = new HashMap();
		map.put("scid", "v_sci");
		map.put("scname", "v_scname");
		map.put("songname", "v_songname1");
		map.put("downlink", "v_downlink1");
		page.add(map);

		map = new HashMap();
		map.put("scid", "v_sci");
		map.put("scname", "v_scname");
		map.put("songname", "v_songname2");
		map.put("downlink", "v_downlink2");
		page.add(map);

		map = new HashMap();
		map.put("scid", "v_sci1");
		map.put("scname", "v_scname");
		map.put("songname", "v_songname3");
		map.put("downlink", "v_downlink3");
		page.add(map);

		map = new HashMap();
		map.put("scid", "v_sci1");
		map.put("scname", "v_scname");
		map.put("songname", "v_songname4");
		map.put("downlink", "v_downlink4");
		page.add(map);

		pageMap.put("pagename3", page);

		Map<String, Map<String, String>> hierarchy = new HashMap();

		// Map<String, List<Map<String, String>>> curUniResultTableMap =new
		// ConcurrentHashMap();
		// ResutTree resutTree = new ResutTree(pageMap,
		// hierarchy,curUniResultTableMap);
		// resutTree.setPageMap(pageMap);
		//
		// String str = "pagename1:P1,pagename2:P2,pagename3:P3;select P1.bcname
		// bcname,P2.scname sncame,P3.songname songname,P3.downlink downlink"
		// + " downlink where P1.bcid=P2.bcid and P2.scid=P3.scid; dao->insert
		// ";
		//
		// int semi = str.lastIndexOf(";");
		//
		// String dao = str.substring(semi + 1);
		// String irql = str.substring(0, semi);
		//
		// ArrayList<Map> am = resutTree.getMapResult(irql);
	}

	public void setMergeMap(Map<String, TableMerge> mergeMap) {
		this.mergeMap = mergeMap;
	}

}
分享到:
评论

相关推荐

    IRQL-thread-中文翻译.doc

    - **IRQL APC_LEVEL**:当线程处于可调度状态并等待APC(异步过程调用)时,IRQL提升至此级别。在此级别,可以执行一些轻量级的同步操作,但不能进行内存分配。 - **IRQL DISPATCH_LEVEL**:这个级别用于处理硬件...

    Scheduling, Thread Context, and IRQL

    - **运行在DISPATCH_LEVEL或更高IRQL的指导原则**:由于这些IRQL级别要求中断处理必须迅速完成,因此编写在这类IRQL级别下运行的代码时需要特别小心,避免长时间的操作。 - **改变驱动程序代码运行的IRQL**:有时...

    Scheduling, Thread Context, and IRQL.pdf

    本文档主要探讨了线程调度(Thread Scheduling)、线程上下文(Thread Context)以及中断请求级别(Interrupt Request Level,简称IRQL)对于Microsoft Windows内核模式驱动程序操作的影响。通过深入理解这些概念,...

    Scheduling, Thread Context, and IRQL.doc

    - **绪论**:本文档旨在探讨线程调度、线程上下文及处理器当前中断请求级别(IRQL)如何影响运行于Microsoft Windows系列操作系统内核模式下的驱动程序的操作。通过深入理解这些概念,驱动开发者能够更好地编写高效...

    深入解析Windows操作系统中文.part2.rar

    公共信息模型(CIM)和可管理对象的格式语言 240 WMI名字空间 243 类关联 244 WMI实现 247 WMI安全性 248 4.4 本章总结 249 第5章 启动和停机 251 5.1 引导过程 251 x86和x64引导准备 251 x86/x64引导扇区和Ntldr ...

    深入解析windows 操作系统第6版第2-3章.中文版扫描

    深入解析windows 操作系统第6版第2-3章.Russinovich.范德成.中文.扫描 内容目录 第2章系统架构 33 2.1 需求和设计目标 33 2.2 操作系统模型 34 2.3 总体架构 35 可移植性 37 对称多处理 38 可伸缩性 40 客户...

    从汇编语言到Windows内核编程

    《从汇编语言到Windows内核编程》是一本深度探讨计算机底层原理和技术的书籍,它旨在帮助读者从基本的汇编语言入手,逐步过渡到高级的Windows操作系统内核的编程技术。汇编语言是计算机科学的基础,理解它有助于我们...

    天书夜读从汇编语言到windows内核编程

    标题《天书夜读从汇编语言到windows内核编程》和描述“以汇编语言为引,带你畅游windows内核,熟悉内核编程”所涉及的知识点包括汇编语言基础、Windows操作系统内核结构、以及在Windows内核层面上进行编程的方法和...

    windows常见蓝屏解析.pdf

    【Windows常见蓝屏解析】 Windows操作系统中的蓝屏现象,全称是Windows停止屏幕,是系统遇到严重错误导致核心组件崩溃或锁定的表现。当蓝屏出现时,系统会显示错误原因和可能的解决方法,但这些信息往往对普通用户...

    电脑蓝屏代码全解析

    ### 电脑蓝屏代码全解析:成为自己的系统管理员 在日常使用电脑的过程中,我们偶尔会遇到令人头疼的“蓝屏”现象,屏幕上出现的一串串代码不仅让人摸不着头脑,更可能打断了我们的工作流程。然而,了解并掌握这些...

    深入解析windows操作系统之崩溃转储分析

    ### 深入解析Windows操作系统之崩溃转储分析 #### 1. Windows为什么会崩溃 Windows系统的崩溃,通常指的是系统在运行过程中遇到了无法处理的错误,从而导致系统进入一种非正常的状态,这种状态往往表现为所谓的...

    win7蓝屏代码解析

    Win7蓝屏代码解析涉及到的是操作系统在运行过程中遇到严重错误时的一种反馈机制。蓝屏(Blue Screen of Death,简称BSoD)是Windows系统的一种错误报告方式,它显示了详细的错误信息,帮助用户和技术人员诊断问题...

    windows蓝屏代码详细解析

    下面,我们将详细解析几个常见的Windows蓝屏错误代码及其可能的原因和解决方法。 ### 1. 错误代码:0x000000A **描述**:IRQL_NOT_LESS_OR_EQUAL **常见原因**: - 驱动程序或硬件设备在高中断请求级别(IRQL)下...

    Windows蓝屏代码详解

    - 搜索解决方案:使用搜索引擎或官方文档,输入错误代码查找可能的原因和解决方法。 - 安全模式启动:如果系统无法正常启动,尝试进入安全模式,这可以禁用可能导致问题的驱动程序。 - 更新驱动程序:检查并更新...

    简单的蓝屏分析器(用JAVA写的)

    Java作为一种跨平台的编程语言,可以用于开发各种应用程序,包括蓝屏分析工具。本项目是一个用Java编写的简单蓝屏分析器,旨在帮助用户理解蓝屏的原因,并提供可能的解决策略。 首先,我们需要理解蓝屏出现的基本...

    深入解析Windows操作系统:第4版:中文第14章

    ### 深入解析Windows操作系统:第4版:中文第14章 #### 章节概述 本章节深入探讨了Windows操作系统中的一个重要主题:**崩溃转储分析**。通过本章的学习,读者将了解导致Windows系统崩溃的各种原因,学会如何解读...

    windows帮助文档

    在Windows操作系统中,管理和优化系统资源的高效运行是至关重要的,这涉及到多个核心概念,如“调度”、“线程上下文”、“IRQL(中断请求级别)”、“锁”以及“死锁与同步”。这些概念构成了Windows内核级操作的...

    win32汇编写的驱动程序框架

    总之,"win32汇编写的驱动程序框架"涉及的知识点包括:汇编语言基础、RADASM汇编器的使用、Windows驱动程序模型(WDM)、PnP和PM机制、中断处理以及IRQL的理解。掌握这些知识,对于深入理解操作系统内核和硬件交互...

    Windows操作系统体系结构二PPT课件.pptx

    《深入解析Windows操作系统体系结构——陷阱与调度》 Windows操作系统的核心在于其精心设计的陷阱调度机制,这使得系统能够高效地处理异常、中断和系统服务请求。陷阱调度是操作系统的关键组成部分,它确保了系统在...

    Windows操作系统体系结构二PPT学习教案.pptx

    SEH是操作系统级别的机制,与特定编程语言的语法结合使用,通过`__try`和`__except`关键字定义保护区域和异常处理程序。异常过滤器用于决定如何处理异常,返回的异常标识符决定是否继续执行、处理异常或继续搜索其他...

Global site tag (gtag.js) - Google Analytics