package com.meidusa.amoeba.mongodb.handler.merge; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import ognl.Ognl; import ognl.OgnlException; import org.bson.BSONObject; import com.meidusa.amoeba.util.ObjectUtil; import com.meidusa.amoeba.util.StringUtil; /** * * @author struct * */ public class GroupReducer { protected Set<String> keys = null; private String[] reducerParams = new String[2]; private String finalizeParam; private Object reduceExpression; private Object finalizeExpression; public void initial(BSONObject keys,String function,String finalize){ if(keys != null){ this.keys = keys.keySet(); } if(function !=null){ String temp[] = StringUtil.split(function, "{}"); String parameters[] = StringUtil.split(temp[0].trim(),"(,)"); reducerParams[0] = parameters[1].trim(); reducerParams[1] = parameters[2].trim(); try { String expression = temp[1].replaceAll(";", ",").trim(); if(expression.endsWith(",")){ expression = expression.substring(0, expression.length() -1); } reduceExpression = Ognl.parseExpression(expression); } catch (OgnlException e) { e.printStackTrace(); } } if(finalize !=null){ String temp[] = StringUtil.split(finalize, "{}"); String parameters[] = StringUtil.split(temp[0].trim(),"(,)"); finalizeParam = parameters[1].trim(); try { String expression = temp[1].replaceAll(";", ",").trim(); if(expression.endsWith(",")){ expression = expression.substring(0, expression.length() -1); } finalizeExpression = Ognl.parseExpression(expression); } catch (OgnlException e) { e.printStackTrace(); } } } public List<BSONObject> reduce(List<List<BSONObject>> inputObjs){ List<BSONObject> output = null; for(List<BSONObject> inputs : inputObjs){ if(inputs == null){ continue; } if(output == null){ output = inputs; } List<BSONObject> notMatchList = null; Map<String,BSONObject> root = new HashMap<String,BSONObject>(2); Map<String,Object> context = new HashMap<String,Object>(); for(BSONObject input : inputs){ _Match_:{ for(BSONObject prev : output ){ if(isMatch(input,prev)){ root.put(reducerParams[0], input); root.put(reducerParams[1], prev); function(context,root); break _Match_; } } if(notMatchList == null){ notMatchList = new ArrayList<BSONObject>(); } notMatchList.add(input); } } if(notMatchList != null){ output.addAll(notMatchList); } } if(output != null){ Map<String,BSONObject> root = new HashMap<String,BSONObject>(2); Map<String,Object> context = new HashMap<String,Object>(); for(BSONObject prev : output ){ root.put(finalizeParam, prev); finalize(context,root); } } return output; } protected boolean isMatch(BSONObject input,BSONObject prev){ if(keys == null){ return true; } for(String key : keys){ if(!ObjectUtil.equals(input.get(key),prev.get(key))){ return false; } } return true; } protected void function(Map<String,Object> context,Map<String,BSONObject> root){ try { Ognl.getValue(reduceExpression, context, root); } catch (OgnlException e) { e.printStackTrace(); } } protected void finalize(Map<String,Object> context,Map<String,BSONObject> root){ try { Ognl.getValue(finalizeExpression, context, root); } catch (OgnlException e) { e.printStackTrace(); } } }