BUG-3876: Add ExprListener and friends 99/47199/2
authorRobert Varga <rovarga@cisco.com>
Thu, 20 Oct 2016 11:47:31 +0000 (13:47 +0200)
committerRobert Varga <nite@hq.sk>
Fri, 21 Oct 2016 09:07:05 +0000 (09:07 +0000)
This adds interfaces for walking the expression tree.

Change-Id: I1b3f9930c7a1ef70b6f2d87762683a86493bd698
Signed-off-by: Robert Varga <rovarga@cisco.com>
yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/ExprListener.java [new file with mode: 0644]
yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/ExprWalker.java [new file with mode: 0644]
yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/JaxenXPath.java
yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/NormalizedNodeNavigator.java
yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/Operator.java [new file with mode: 0644]
yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/StepListener.java [new file with mode: 0644]

diff --git a/yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/ExprListener.java b/yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/ExprListener.java
new file mode 100644 (file)
index 0000000..ab19aac
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.jaxen;
+
+import java.util.Optional;
+import org.jaxen.expr.BinaryExpr;
+import org.jaxen.expr.FilterExpr;
+import org.jaxen.expr.FunctionCallExpr;
+import org.jaxen.expr.LiteralExpr;
+import org.jaxen.expr.LocationPath;
+import org.jaxen.expr.NumberExpr;
+import org.jaxen.expr.PathExpr;
+import org.jaxen.expr.UnaryExpr;
+import org.jaxen.expr.VariableReferenceExpr;
+
+abstract class ExprListener {
+    void enterBinaryExpr(final BinaryExpr expr) {
+
+    }
+    void exitBinaryExpr(final BinaryExpr expr) {
+
+    }
+
+    void enterFilterExpr(final FilterExpr expr) {
+
+    }
+
+    void exitFilterExpr(final FilterExpr expr) {
+
+    }
+
+    void enterFunctionCallExpr(final FunctionCallExpr expr) {
+
+    }
+
+    void exitFunctionCallExpr(final FunctionCallExpr expr) {
+
+    }
+
+    void enterNotExpr(final UnaryExpr expr) {
+
+    }
+
+    void exitNotExpr(final UnaryExpr expr) {
+
+    }
+
+    Optional<StepListener> enterLocationPath(final LocationPath path) {
+        return Optional.empty();
+    }
+
+    void exitLocationPath(final LocationPath path) {
+
+    }
+
+    void enterPathExpr(final PathExpr expr) {
+
+    }
+
+    void exitPathExpr(final PathExpr expr) {
+
+    }
+
+    void visitLiteralExpr(final LiteralExpr expr) {
+
+    }
+
+    void visitNumberExpr(final NumberExpr expr) {
+
+    }
+
+    void visitOperator(final Operator oper) {
+
+    }
+
+    void visitVariableReferenceExpr(final VariableReferenceExpr expr)  {
+
+    }
+}
diff --git a/yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/ExprWalker.java b/yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/ExprWalker.java
new file mode 100644 (file)
index 0000000..6e926f5
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.jaxen;
+
+import com.google.common.base.Preconditions;
+import java.util.Optional;
+import org.jaxen.expr.AllNodeStep;
+import org.jaxen.expr.BinaryExpr;
+import org.jaxen.expr.CommentNodeStep;
+import org.jaxen.expr.Expr;
+import org.jaxen.expr.FilterExpr;
+import org.jaxen.expr.FunctionCallExpr;
+import org.jaxen.expr.LiteralExpr;
+import org.jaxen.expr.LocationPath;
+import org.jaxen.expr.NameStep;
+import org.jaxen.expr.NumberExpr;
+import org.jaxen.expr.PathExpr;
+import org.jaxen.expr.ProcessingInstructionNodeStep;
+import org.jaxen.expr.TextNodeStep;
+import org.jaxen.expr.UnaryExpr;
+import org.jaxen.expr.VariableReferenceExpr;
+
+final class ExprWalker {
+    private final ExprListener listener;
+
+    ExprWalker(final ExprListener listener) {
+        this.listener = Preconditions.checkNotNull(listener);
+    }
+
+    public void walk(final Expr expr) {
+        if (expr instanceof BinaryExpr) {
+            final BinaryExpr binary = (BinaryExpr) expr;
+            listener.enterBinaryExpr(binary);
+            walk(binary.getLHS());
+            listener.visitOperator(Operator.forString(binary.getOperator()));
+            walk(binary.getRHS());
+            listener.exitBinaryExpr(binary);
+        } else if (expr instanceof FilterExpr) {
+            final FilterExpr filter = (FilterExpr) expr;
+            listener.enterFilterExpr(filter);
+            walk(expr);
+            listener.exitFilterExpr(filter);
+        } else if (expr instanceof FunctionCallExpr) {
+            final FunctionCallExpr func = (FunctionCallExpr) expr;
+            listener.enterFunctionCallExpr(func);
+
+            for (Object arg : func.getParameters()) {
+                walk((Expr) arg);
+            }
+
+            listener.exitFunctionCallExpr(func);
+        } else if (expr instanceof LiteralExpr) {
+            listener.visitLiteralExpr((LiteralExpr) expr);
+        } else if (expr instanceof LocationPath) {
+            final LocationPath path = (LocationPath) expr;
+            final Optional<StepListener> maybeListener = listener.enterLocationPath(path);
+            if (maybeListener.isPresent()) {
+                final StepListener l = maybeListener.get();
+                for (Object step : path.getSteps()) {
+                    if (step instanceof AllNodeStep) {
+                        l.onAll((AllNodeStep) step);
+                    } else if (step instanceof CommentNodeStep) {
+                        l.onComment((CommentNodeStep) step);
+                    } else if (step instanceof NameStep) {
+                        l.onName((NameStep) step);
+                    } else if (step instanceof ProcessingInstructionNodeStep) {
+                        l.onProcessingInstruction((ProcessingInstructionNodeStep) step);
+                    } else if (step instanceof TextNodeStep) {
+                        l.onTest((TextNodeStep) step);
+                    } else {
+                        throw new IllegalArgumentException("Unsupported step " + step);
+                    }
+                }
+            }
+
+            listener.exitLocationPath(path);
+        } else if (expr instanceof NumberExpr) {
+            listener.visitNumberExpr((NumberExpr) expr);
+        } else if (expr instanceof PathExpr) {
+            final PathExpr path = (PathExpr) expr;
+            listener.enterPathExpr(path);
+            walk(path.getFilterExpr());
+            walk(path.getLocationPath());
+            listener.exitPathExpr(path);
+        } else if (expr instanceof UnaryExpr) {
+            final UnaryExpr unary = (UnaryExpr) expr;
+            listener.enterNotExpr(unary);
+            walk(unary.getExpr());
+            listener.exitNotExpr(unary);
+        } else if (expr instanceof VariableReferenceExpr) {
+            listener.visitVariableReferenceExpr((VariableReferenceExpr) expr);
+        } else {
+            throw new IllegalArgumentException("Unsupported expression " + expr);
+        }
+    }
+}
index 663cd528f25b6f99b9dbf2d2639e94f01fd7c0fa..331d80ddeb854266458d076fe179836918ff2e6e 100644 (file)
@@ -60,7 +60,9 @@ final class JaxenXPath implements XPathExpression {
         final Expr expr = compiled.getRootExpr();
         LOG.debug("Compiled {} to expression {}", xpath, expr);
 
-        // FIXME: perform expression introspection to understand things like apex, etc.
+        new ExprWalker(new ExprListener() {
+            // FIXME: perform expression introspection to understand things like apex, etc.
+        }).walk(expr);
 
         return new JaxenXPath(converter, schemaPath, compiled);
     }
index 143510255f224b1f89a01156ff62f9d86e18fe77..0954ecfb922b549273f9a866096addd90b087269 100644 (file)
@@ -262,9 +262,9 @@ final class NormalizedNodeNavigator extends DefaultNavigator implements NamedAcc
         final NormalizedNode<?, ?> node = ctx.getNode();
         if (node instanceof DataContainerNode) {
             return Iterators.transform(((DataContainerNode<?>) node).getValue().iterator(), ctx);
-        } else {
-            return null;
         }
+
+        return null;
     }
 
     @Override
diff --git a/yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/Operator.java b/yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/Operator.java
new file mode 100644 (file)
index 0000000..4774ef7
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.jaxen;
+
+enum Operator {
+    EQUALS,
+    NOT_EQUALS,
+    GREATER_THAN,
+    GREATER_THAN_EQUALS,
+    LESS_THAN,
+    LESS_THAN_EQUALS,
+    MINUS,
+    PLUS,
+    AND,
+    OR,
+    DIV,
+    MOD,
+    MULTIPLY,
+    UNION;
+
+    static Operator forString(final String str) {
+        switch (str) {
+            case "=":
+                return Operator.EQUALS;
+            case "!=":
+                return Operator.NOT_EQUALS;
+            case "-":
+                return Operator.MINUS;
+            case "+":
+                return Operator.PLUS;
+            case "and":
+                return Operator.AND;
+            case "or":
+                return Operator.OR;
+            case "div":
+                return Operator.DIV;
+            case "mod":
+                return Operator.MOD;
+            case "*":
+                return Operator.MULTIPLY;
+            case ">=":
+                return Operator.GREATER_THAN_EQUALS;
+            case ">":
+                return Operator.GREATER_THAN;
+            case "<=":
+                return Operator.LESS_THAN_EQUALS;
+            case "<":
+                return Operator.LESS_THAN;
+            case "|":
+                return Operator.UNION;
+            default:
+                throw new IllegalArgumentException("Unknown operator " + str);
+
+        }
+    }
+}
diff --git a/yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/StepListener.java b/yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/StepListener.java
new file mode 100644 (file)
index 0000000..ce2f6b2
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.jaxen;
+
+import org.jaxen.expr.AllNodeStep;
+import org.jaxen.expr.CommentNodeStep;
+import org.jaxen.expr.NameStep;
+import org.jaxen.expr.ProcessingInstructionNodeStep;
+import org.jaxen.expr.TextNodeStep;
+
+abstract class StepListener {
+    void onAll(final AllNodeStep step) {
+
+    }
+    void onComment(final CommentNodeStep step) {
+
+    }
+    void onName(final NameStep step) {
+
+    }
+    void onProcessingInstruction(final ProcessingInstructionNodeStep step) {
+
+    }
+    void onTest(final TextNodeStep step) {
+
+    }
+}