`
mengke
  • 浏览: 7630 次
  • 性别: Icon_minigender_1
  • 来自: 南通
文章分类
社区版块
存档分类
最新评论

jxls 升级 jexl 1.1 至 2.X 支持中文标签

阅读更多
修改net.sf.jxls.parser包下的
Expression


package net.sf.jxls.parser;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.jxls.transformer.Configuration;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.jexl2.JexlEngine;
import org.apache.commons.jexl2.MapContext;


/**
 * Represents JEXL expression
 * @author Leonid Vysochyn
 */
public class Expression {

    public static final String aggregateSeparator = "[a-zA-Z()]+[0-9]*:";

    String expression;
    String rawExpression;
    String aggregateFunction;
    String aggregateField;
    Map beans;
    List properties = new ArrayList();
    org.apache.commons.jexl2.Expression jexlExpresssion;

    Configuration config;

    Property collectionProperty;

    public Property getCollectionProperty() {
        return collectionProperty;
    }

    public List getProperties() {
        return properties;
    }

    public String getExpression() {
        return expression;
        
    }

    public Expression(String expression, Configuration config) {
        this.expression = expression;
        this.config = config;
    }

    public Expression(String expression, Map beans, Configuration config) throws Exception {
        this.config = config;
        this.expression = expression;
        this.rawExpression = parseAggregate(expression);
        this.beans = beans;
        //修改表达式 创建方法
        JexlEngine JEXL = new JexlEngine();
       jexlExpresssion = JEXL.createExpression("map."+rawExpression);
        
        
       // jexlExpresssion = ExpressionFactory.createExpression( rawExpression );
        
        
        
        
        
        
        parse();
    }
    private void parse() {
        Property prop = new Property(rawExpression, beans, config);
        this.properties = new ArrayList();
        this.properties.add(prop);
        if (prop.isCollection() && aggregateFunction == null && collectionProperty == null) {
            this.collectionProperty = prop;
        }
    }
    
    
    
    public Object evaluate() throws Exception {
        if (beans != null && !beans.isEmpty()){
            /*-------------------开始修改------------------------------*/
            org.apache.commons.jexl2.JexlContext jc = new MapContext();
            jc.set("map", beans); //jexl 2 开始必须要名称 默认设置一个名称map
	        Object ret = jexlExpresssion.evaluate(jc);
            
	        
	        JexlEngine JEXL1 = new JexlEngine();
	            org.apache.commons.jexl2.Expression e = JEXL1.createExpression("map."+rawExpression);//在表达式中增加 我在前面设置的名称 map
		        Object ret1 = jexlExpresssion.evaluate(jc);
		        /*-------------------结束修改------------------------------*/
            if (aggregateFunction != null) {
            	return calculateAggregate(aggregateFunction, aggregateField, ret);
            }
            return ret;
        }
        return expression;
    }

    private String parseAggregate(String expr)
    {
        String[] aggregateParts = expr.split(aggregateSeparator, 2);
    	int i = expr.indexOf(":");
    	if (aggregateParts.length >= 2 && i >= 0) {
    		String aggregate = expr.substring(0, i);
    		if (aggregate.length() == 0) {
    			aggregateFunction = null;
    			aggregateField = null;
    		}
    		else {
    			int f1 = aggregate.indexOf("(");
    			int f2 = aggregate.indexOf(")");
    			if (f1 != -1 && f2 != -1 && f2 > f1) {
    				aggregateFunction = aggregate.substring(0, f1);
    				aggregateField = aggregate.substring(f1+1, f2);
    			}
    			else {
    				aggregateFunction = aggregate;
    				aggregateField = "c1";
    			}
    		}
    		return expr.substring(i+1);
    	}
        aggregateFunction = null;
        aggregateField = null;
        return expr;
    }
    


    private Object calculateAggregate(String function, String field, Object list)
    {
    	Aggregator agg = Aggregator.getInstance(function);
    	if (agg != null) {
    		if (list instanceof Collection) {
	    		Collection coll = (Collection) list;
                for (Iterator iterator = coll.iterator(); iterator.hasNext();) {
                    Object o = iterator.next();
	    			try {
		    			Object f = PropertyUtils.getProperty(o, field);
		    			agg.add(f);
	    			}
	    			catch (InvocationTargetException e) {
	    				e.printStackTrace();
	    			}
	    			catch (NoSuchMethodException e) {
	    				e.printStackTrace();
	    			}
	    			catch (IllegalAccessException e) {
	    				e.printStackTrace();
	    			}
	    		}
    		}
    		else {
    			try {
    				Object f = PropertyUtils.getProperty(list, field);
    				agg.add(f);
    			}
    			catch (InvocationTargetException e) {
    				e.printStackTrace();
    			}
    			catch (NoSuchMethodException e) {
    				e.printStackTrace();
    			}
    			catch (IllegalAccessException e) {
    				e.printStackTrace();
    			}
    		}
    		return agg.getResult();
    	}
        return list;
    }
    
    public String toString() {
        return expression;
    }
}




ExpressionCollectionParser

package net.sf.jxls.parser;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.jexl2.Expression;
import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.JexlEngine;
import org.apache.commons.jexl2.parser.ASTIdentifier;
import org.apache.commons.jexl2.parser.ASTReference;
import org.apache.commons.jexl2.parser.Node;
import org.apache.commons.jexl2.parser.Parser;
import org.apache.commons.jexl2.parser.SimpleNode;


public class ExpressionCollectionParser {
    
    public final static String COLLECTION_REFERENCE_SUFFIX = "_JxLsC_";

    // This is set up as a ThreadLocal parser to avoid threading issues.
    private static ThreadLocal parser = new ThreadLocal() {
        protected synchronized Object initialValue() {
            return new Parser(new StringReader(";"));
        }
    };

    private boolean jexlInnerCollectionsAccess;


    private String collectionExpression;
    private Collection collection;
    
    public ExpressionCollectionParser(org.apache.commons.jexl2.JexlContext jexlContext, String expr, boolean jexlInnerCollectionsAccess) {
        try {
            this.jexlInnerCollectionsAccess = jexlInnerCollectionsAccess;
            SimpleNode tree = ((Parser) parser.get()).parse(new StringReader(expr),null);
            ArrayList references = new ArrayList();
            findReferences(references, tree);
            findCollection(jexlContext, references);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String getCollectionExpression() {
        return collectionExpression;
    }
    
    public Collection getCollection() {
        return collection;
    }
    
    private void findReferences(List references, Node node) {
        
        if (node instanceof ASTReference) {
            references.add(node);
        }
        
        int childCount = node.jjtGetNumChildren();
        for (int i = 0; i < childCount; i++) {
            findReferences(references, node.jjtGetChild(i));
        }
    }
    
    private void findCollection(JexlContext jexlContext, List references) {
        
        Node node;
        
        for (Iterator itr = references.iterator(); itr.hasNext();) {
            node = (Node) itr.next();
            String newExpression = findCollectionProperties(jexlContext, node);
            if (newExpression != null) {
                if (!newExpression.endsWith(COLLECTION_REFERENCE_SUFFIX)) {
                    this.collectionExpression = newExpression;
                }
                break;
            }
        }
    }
    
    private String findCollectionProperties(JexlContext jexlContext, Node node) {
        
        int childCount = node.jjtGetNumChildren();
        Node child  ;
        String subExpr = null;
        
        for (int i = 0; i < childCount; i++) {
            child = node.jjtGetChild(i);
            if (child instanceof ASTIdentifier) {
                ASTIdentifier ident = (ASTIdentifier) child;
                if (subExpr == null) {
                    subExpr =ident.image;
                } else {
                    subExpr = subExpr + "." + ident.image;;
                	
                }
                if( jexlInnerCollectionsAccess ){
                    if (subExpr.endsWith(COLLECTION_REFERENCE_SUFFIX)) {
                        return subExpr;
                    }
                }
                try {
                	
                	JexlEngine JEXL = new JexlEngine();
        	        Expression e = JEXL.createExpression("map."+subExpr);
//                    Expression e = ExpressionFactory.createExpression(subExpr);
                    Object obj = e.evaluate(jexlContext);
                    if (obj instanceof Collection) {
                        this.collection = (Collection) obj;
                        return subExpr;
                    }
                } catch (Exception e) {
                    // TODO: insert proper logging here
                    return null;
                }
            }
        }
        
        return null;
    }    
}


Property

package net.sf.jxls.parser;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import net.sf.jxls.transformer.Configuration;


import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.MapContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Represents a property in excel template
* @author Leonid Vysochyn
*/
public class Property {
    protected final Log log = LogFactory.getLog(getClass());
    List propertyTokens = new ArrayList();

    private String beanName;
    private Object bean;
    private String collectionName;
    private Collection collection;

    private String property;
    private Object propertyValue;

    Configuration config;

    public Property(String value) {
        propertyValue = value;
    }

    public Property(String property, Map beans, Configuration config) {
        this.property = property;
        this.config = config;
        propertyValue = getPropertyValue(beans);
    }

    public boolean isConstant(){
        return property==null;
    }

    public Object getPropertyValue(Map beans) {
    JexlContext jc = new MapContext();
    jc.set("map", beans);
//        JexlContext context = JexlHelper.createContext();
//        context.setVars(beans);
        ExpressionCollectionParser parser = new ExpressionCollectionParser(jc,this.property + ";", config.isJexlInnerCollectionsAccess());
        if (parser.getCollection() == null) {
            propertyValue = null;
        } else {
            collectionName = parser.getCollectionExpression();
            collection = parser.getCollection();
            beanName = null;
            bean = null;
        }
       
        return propertyValue;
    }

    public boolean isCollection() {
        return collectionName != null;
    }

    public boolean isNull() {
        return getPropertyValue() == null;
    }

    public String getBeanName() {
        return beanName;
    }

    public String getCollectionName() {
        return collectionName;
    }

    public void setCollectionName(String collectionName) {
        this.collectionName = collectionName;
    }


    public String getProperty() {
        return property;
    }


    public Collection getCollection() {
        return collection;
    }

    public void setCollection(Collection collection) {
        this.collection = collection;
    }

    public String getFullCollectionName() {
        if (beanName == null) {
            return collectionName;
        }
        return beanName + "." + collectionName;
    }

    public String getPropertyNameAfterLastDot() {
        String propertyName = null;
        if (property != null) {
            int dotIndex = property.lastIndexOf(".");
            if (dotIndex >= 0) {
                propertyName = property.substring(dotIndex + 1);
            } else {
                propertyName = property;
            }
        }
        return propertyName;
    }

    public String getPropertyNameAfterFirstDot() {
        String propertyName = null;
        if (property != null) {
            int dotIndex = property.indexOf(".");
            if (dotIndex >= 0) {
                propertyName = property.substring(dotIndex + 1);
            } else {
                propertyName = property;
            }
        }
        return propertyName;
    }

    public String toString() {
        return "Property{" +
                "property='" + property + "'}";
    }

    public Object getPropertyValue() {
        if( bean instanceof String){
            return bean;
        }
        return propertyValue;
    }

    public void setPropertyValue(Object propertyValue) {
        this.propertyValue = propertyValue;
    }

    public Object getBean() {
        return bean;
    }

    public void setBean(Object bean) {
        this.bean = bean;
    }

}







分享到:
评论
1 楼 jaw111 2014-04-15  
非常感谢!!!
JEXL1对中文支持不是很好,刚好需要用JXLS绑定JEXL2.

相关推荐

Global site tag (gtag.js) - Google Analytics