Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.envoisolutions.sxc.xpath;
  
 
 import java.util.List;
 import java.util.Map;
 
 
 import  org.jaxen.JaxenHandler;
 import  org.jaxen.expr.AllNodeStep;
 import  org.jaxen.expr.EqualityExpr;
 import  org.jaxen.expr.Expr;
 import  org.jaxen.expr.FunctionCallExpr;
 import  org.jaxen.expr.LiteralExpr;
 import  org.jaxen.expr.LocationPath;
 import  org.jaxen.expr.LogicalExpr;
 import  org.jaxen.expr.NameStep;
 import  org.jaxen.expr.NumberExpr;
 import  org.jaxen.expr.Predicate;
 import  org.jaxen.expr.TextNodeStep;
 import  org.jaxen.expr.XPathExpr;
 import  org.jaxen.saxpath.Axis;
 import  org.jaxen.saxpath.SAXPathException;
 import  org.jaxen.saxpath.helpers.XPathReaderFactory;
 
 public class XPathBuilder {
     private Map<String,StringnamespaceContext;
     private ElementParserBuilder parserBldr;
     
     private Map<StringObjectvars = new HashMap<StringObject>();
     private JType eventHandlerType;
     private JType stringType;
     private Builder builder;
     private JType eventType;
     private int varCount = 0;
     private int elementCounters = 0;
     private JPrimitiveType boolType;
     private JPrimitiveType intType;
     private JCodeModel model;
 
     public XPathBuilder() {
         super();
         
          = new BuilderImpl();
          = .getParserBuilder();
         
          = .getCodeModel();
          = ._ref(XPathEventHandler.class);
          = ._ref(XPathEvent.class);
          = ._ref(String.class);
          = .;
          = .;
     }
 
     public void listen(String exprXPathEventHandler handler) {
         .put(exprhandler);
     }
     
     public XPathEvaluator compile() {
         for (Map.Entry<StringXPathEventHandlere : .entrySet()) {
             compileEventHandler(e.getKey(), e.getValue());
         }
         
         Context context = .compile();
         context.putAll();
         
         return new XPathEvaluatorImpl(context);
     }
     
     public void compileEventHandler(String exprXPathEventHandler eventHandler) {
         String varName = "obj" + .size();
         .put(varNameeventHandler);
         
         ParserBuilder xpathBuilder = ;
         JBlock block;
         try {
             org.jaxen.saxpath.XPathReader reader = XPathReaderFactory.createReader();
             
             JaxenHandler handler = new JaxenHandler();
             reader.setXPathHandler(handler);
             reader.parse(expr);
             
            XPathExpr path = handler.getXPathExpr(true);
            
            Object o = handleExpression(path.getRootExpr());
            if (o instanceof ExpressionState) {
                ExpressionState exp = (ExpressionStateo;
                JVar var = exp.getVar();
                ParserBuilder builder = exp.getBuilder();
                block = builder.getBody().getBlock();
                
                block = block._if(var)._then();
            } else {
                xpathBuilder = (ParserBuildero;
                block = xpathBuilder.getBody().getBlock();
            }
        } catch (SAXPathException e) {
            throw new XPathException(e);
        }
        
        CodeBody body = xpathBuilder.getBody();
        
        // grab the event handler out of the context
        JVar handlerVar = block.decl(varName
                                    JExpr.cast(
                                               JExpr._super().ref("context").invoke("get").arg(varName)));
        block.add(handlerVar.invoke("onMatch").arg(JExpr._new().arg(JExpr.lit(expr)).arg(xpathBuilder.getXSR())));
    }
    private Object handleExpression(ElementParserBuilder xpathBuilder, Expr expr) {
        // System.out.println("Expression " + expr);
        if (expr instanceof LocationPath) {
            return handle(xpathBuilder, (LocationPath) expr);
        } else if (expr instanceof EqualityExpr) {
            return handle(xpathBuilder, (EqualityExpr) expr);
        } else if (expr instanceof LiteralExpr) {
            return handle(xpathBuilder, (LiteralExpr) expr);
        } else if (expr instanceof FunctionCallExpr) {
            return handle(xpathBuilder, (FunctionCallExpr) expr);
        } else if (expr instanceof LogicalExpr) {
            return handle(xpathBuilder, (LogicalExpr) expr);
        } else if (expr instanceof NumberExpr) {
            return handle(xpathBuilder, (NumberExpr) expr);
        } else {
            throw new XPathException("Unknown expression type " + expr);
        }
    }
    private ExpressionState handle(ElementParserBuilder xpathBuilder, LiteralExpr expr) {
        JVar var = xpathBuilder.getBody().decl(
                                               "_literal" + ++,
                                               JExpr.lit(expr.getLiteral()));
        return new ExpressionState(xpathBuildervar);
    }
    
    private ParserBuilder handle(ElementParserBuilder parent, LogicalExpr expr) {
        Object left = handleExpression(parentexpr.getLHS());
        Object right = handleExpression(parentexpr.getRHS());
        
        JBlock block = parent.getBody().getBlock();
        
        JVar b1 = ((ExpressionStateleft).getVar();
        JVar b2 = ((ExpressionStateright).getVar();
        
        String op = expr.getOperator();
        
        JBlock newBlock;
        if (op.equals("and")) {
            newBlock = block._if(b1.cand(b2))._then();
        } else if (op.equals("or")) {
            newBlock = block._if(b1.cor(b2))._then();
        } else {
            throw new UnsupportedOperationException("Operator " + op + " is not supported");
        }
        
        return parent.newState(newBlock);
    }
    
    private ExpressionState handle(ElementParserBuilder xpathBuilder, FunctionCallExpr expr) {
        String name = "functValue" + ++;
        String functionName = expr.getFunctionName();
        JVar var;
        // See http://www.w3schools.com/xpath/xpath_functions.asp for a complete list
        if ("local-name".equals(functionName)) {
            var =  xpathBuilder.getBody().decl(
                                               name
                                               xpathBuilder.getXSR().invoke("getLocalName"));
        } else if ("namespace-uri".equals(functionName)) {
            var =  xpathBuilder.getBody().decl(
                                               name
                                               xpathBuilder.getXSR().invoke("getNamespaceURI"));
        } else {
            throw new XPathException("Function " + functionName + " is not understood!");
        }
        
        return new ExpressionState(xpathBuildervar);
    }
    private ExpressionState handle(ElementParserBuilder parent, EqualityExpr expr) {
        Object leftObj = handleExpression(parentexpr.getLHS());
        ExpressionState right = (ExpressionStatehandleExpression(parentexpr.getRHS());
        
        JVar leftVar;
        JVar rightVar;
        ParserBuilder parent2
        if (leftObj instanceof ParserBuilder) {
            // We've got an attribute.. i.e. [@foo='bar']
            ParserBuilder attBuilder = (ParserBuilderleftObj;
            leftVar = attBuilder.as(String.class);
            rightVar = attBuilder.passParentVariable(right.getVar());
            parent2 = attBuilder;
        } else {
            leftVar = ((ExpressionStateleftObj).getVar();
            rightVar = right.getVar();
            parent2 = parent;
        }
        
        JVar var = parent2.getBody().decl(,
                                          "b" + ++,
                                          leftVar.invoke("equals").arg(rightVar));
        
        return new ExpressionState(parent2var);
    }
    private Object handle(ElementParserBuilder xpathBuilder, LocationPath path) {
        Object returnObj = xpathBuilder;
        
        // look for the next part on all child elements
        boolean globalElement = false;
        for (Iterator itr = path.getSteps().iterator(); itr.hasNext();) {
            Object o = itr.next();
            
            if (o instanceof NameStep) {
                returnObj = handleNameStep((ParserBuilderreturnObj, (NameStep) oglobalElement);
                globalElement = false;
            } else if (o instanceof AllNodeStep) {
                globalElement = true;
            } else if (o instanceof TextNodeStep) {
                returnObj = handleTextNodeStep((ParserBuilderreturnObj, (TextNodeStep) o);
            } else {
                throw new XPathException("Unsupported expression: " + o);
            }
        }
        
        return returnObj;
    }
    private ExpressionState handleTextNodeStep(ParserBuilder returnBuilder, TextNodeStep step) {
        JVar var = returnBuilder.as(String.class);
        return new ExpressionState(returnBuildervar);
    }
    private Object handleNameStep(ParserBuilder returnBuilder, NameStep stepboolean globalElement) {
        String prefix = step.getPrefix();
        String ns = "";
        if (prefix != null && !prefix.equals("")) {
            ns = .get(prefix);
            
            if (ns == null) {
                throw new XPathException("Could not find namespace for prefix: " + prefix);
            }
        }
        
        QName n = new QName(nsstep.getLocalName());
        
        ElementParserBuilder elBuilder = ((ElementParserBuilderreturnBuilder);
        if (step.getAxis() == Axis.CHILD) {
            if (n.getLocalPart().equals("*")) {
                returnBuilder = elBuilder.expectAnyElement();
            } else if (globalElement) {
                returnBuilder = elBuilder.expectGlobalElement(n);
            } else {
                returnBuilder = elBuilder.expectElement(n);
            }
        } else if (step.getAxis() == Axis.ATTRIBUTE) {
            returnBuilder = elBuilder.expectAttribute(n);
        } else {
            throw new XPathException("Unsupported axis: " + step.getAxis());
        }
        
        return handlePredicates(returnBuilderstep.getPredicateSet().getPredicates());
    }
    private Object handle(ElementParserBuilder xpathBuilder, NumberExpr expr) {
//        xpathBuilder = xpathBuilder.newState();
        
	JBlock block = xpathBuilder.getBody().getBlock();
        JVar counterVar = .getBody().field(."counter" + ++, JExpr.lit(0));
        
        block.assignPlus(counterVar, JExpr.lit(1));
	JBlock then = block._if(counterVar.eq(JExpr.lit((int) Double.valueOf(expr.getText()).doubleValue())))._then();
	return xpathBuilder.newState(then);
    }
    private Object handlePredicates(ParserBuilder returnBuilderList<?> predicates) {
        Object returnObj = returnBuilder;
        for (Iterator<?> pitr = predicates.iterator(); pitr.hasNext();) {
            Predicate p = (Predicate) pitr.next();
            
            returnObj = 
                handleExpression((ElementParserBuilderreturnObjp.getExpr());
        }
        return returnObj;
    }
    public Map<StringStringgetNamespaceContext() {
        return ;
    }    
    public void setNamespaceContext(Map<StringStringnamespaceContext) {
        this. = namespaceContext;
    }
    public void addPrefix(String prefixString namespace) {
        if ( == null) {
             = new HashMap<StringString>();
        }
        .put(prefixnamespace);
    }
    
    public void addAllPrefixes(Map<StringStringprefixes) {
        if ( == null) {
             = new HashMap<StringString>();
        }
        .putAll(prefixes);
    }
    
    public static class ExpressionState {
        private JVar var;
        private ParserBuilder builder;
        public ExpressionState(ParserBuilder builderJVar var) {
            this. = builder;
            this. = var;
        }
        public ParserBuilder getBuilder() {
            return ;
        }
        public void setBuilder(ParserBuilder builder) {
            this. = builder;
        }
        public JVar getVar() {
            return ;
        }
        public void setVar(JVar var) {
            this. = var;
        }
        
    }
New to GrepCode? Check out our FAQ X