All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aegisql.java_path.JavaPathParser Maven / Gradle / Ivy

There is a newer version: 0.2.3
Show newest version
package com.aegisql.java_path;

import com.aegisql.java_path.parser.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.StringReader;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * The type Java path parser.
 */
public class JavaPathParser {

    private final static Logger LOG = LoggerFactory.getLogger(JavaPathParser.class);

    private static class Visitor implements CCJavaPathParserVisitor {

        private LinkedList> stack = new LinkedList<>();
        private LinkedList rootPath;
        private LinkedList currentPath;
        private int maxBackRef = 0;
        private boolean option;
        private int pathNumber = 0;

        /**
         * Instantiates a new Visitor.
         *
         * @param rootPath the root path
         */
        public Visitor(LinkedList rootPath) {
            this.rootPath = rootPath;
            this.currentPath = rootPath;
        }

        private String toString(Object o) {
            return o == null ? null : o.toString();
        }

        @Override
        public Object visit(SimpleNode node, Object data) {
            return node.childrenAccept(this,data);
        }

        @Override
        public Object visit(ASTcomma node, Object data) {
            if(stack.size() > 0) {
                currentPath = stack.pop();
            }
            LOG.trace("parse:, current: {} stack: {}",currentPath, stack);
            return node.childrenAccept(this,data);
        }

        @Override
        public Object visit(ASTlParenthesis node, Object data) {
            if(stack.size() > 0) {
                stack.push(currentPath);
            }
            LOG.trace("parse:( current: {} stack: {}",currentPath, stack);
            return node.childrenAccept(this,data);
        }

        @Override
        public Object visit(ASTrParenthesis node, Object data) {
            if(stack.size() > 0) {
                currentPath = stack.pop();
            }
            LOG.trace("parse:) current: {} stack: {}",currentPath, stack);
            return node.childrenAccept(this,data);
        }

        @Override
        public Object visit(ASToption node, Object data) {
            option = (boolean) node.jjtGetValue();
            LOG.trace("parse:? current: {} stack: {}",currentPath, stack);
            return node.childrenAccept(this,data);
        }

        @Override
        public Object visit(ASTpathSeparator node, Object data) {
            LOG.trace("parse:; current: {} stack: {}",currentPath, stack);
            pathNumber++;
            rootPath.add(null);
            return node.childrenAccept(this,data);
        }

        @Override
        public Object visit(ASTparse node, Object data) {
            TypedPathElement typedPathElement = (TypedPathElement) node.jjtGetValue();
            if(typedPathElement != null) {
                currentPath.add(typedPathElement);
            }
            LOG.trace("parse:parse {}, {} stack: {}",node.jjtGetValue(),typedPathElement,stack);
            return node.childrenAccept(this,data);
        }

        @Override
        public Object visit(ASTfullPath node, Object data) {
            currentPath = rootPath;
            stack.clear();
            TypedPathElement typedPathElement = new TypedPathElement();
            String fullType = toString(node.jjtGetValue());
            String type = null;
            String factory = null;
            if(fullType != null) {
                String[] pair = fullType.split("::",2);
                type = pair[0];
                if(pair.length == 2) {
                    factory = pair[1];
                }
            }
            typedPathElement.setType(type);
            typedPathElement.setFactory(factory);
            if(option) {
                currentPath.getLast().setOptionalPathElement(typedPathElement);
            } else {
                currentPath.add(typedPathElement);
            }
            LOG.trace("parse:fullPath type: '{}' {} current: {}",fullType,typedPathElement, currentPath);
            return node.childrenAccept(this,data);
        }

        @Override
        public Object visit(ASTpathElement node, Object data) {
            TypedPathElement typedPathElement = null;
            if(stack.size() > 0) {
                typedPathElement = new TypedPathElement();
                TypedPathElement last;
                if(option) {
                    last = rootPath.getLast().getOptionalPathElement();
                } else {
                    last = rootPath.getLast();
                }
                typedPathElement.setType(last.getParameters().getLast().getType());
                currentPath.add(typedPathElement);
            } else {
                if (option) {
                    typedPathElement = currentPath.getLast().getOptionalPathElement();
                } else {
                    typedPathElement = currentPath.getLast();
                }
            }
            typedPathElement.setName(toString(node.jjtGetValue()));
            maxBackRef++;
            LOG.trace("parse:pathElement '{}' maxBackRef {} current: {} stack: {}",node.jjtGetValue(), maxBackRef, currentPath, stack);
            return node.childrenAccept(this,data);
        }

        @Override
        public Object visit(ASTparameters node, Object data) {
            TypedValue typedValue = (TypedValue) node.jjtGetValue();
            TypedPathElement typedPathElement;
            if(option) {
                typedPathElement = currentPath.getLast().getOptionalPathElement();
            } else {
                typedPathElement = currentPath.getLast();
            }
            typedPathElement.addParameter(typedValue);
            if(typedValue.isHashSign()) {
                if(typedValue.getBackRefIdx() >= maxBackRef) {
                    throw new JavaPathRuntimeException("Back reference #"+typedValue.getBackRefIdx()+" is not visible at position "+maxBackRef);
                }
                stack.push(currentPath);
                currentPath = typedValue.getTypedPathElements();
            } else if(typedValue.isDollarSign()) {
                stack.push(currentPath);
                currentPath = typedValue.getTypedPathElements();
            }
            LOG.trace("parse:parameters '{}' current: {} stack: {}",typedValue,currentPath,stack);
            return node.childrenAccept(this,data);
        }

    }


    /**
     * Parse list.
     *
     * @param path the path
     * @return the list
     */
    public static List parse(String path) {
        LOG.debug("parsing {}",path);
        LinkedList elements = new LinkedList<>();
        Visitor visitor = new Visitor(elements);
        CCJavaPathParser parser = new CCJavaPathParser(r(path));
        SimpleNode sn = null;
        try {
            sn = parser.parse();
            sn.jjtAccept(visitor,elements);
        } catch (ParseException e) {
            throw new JavaPathRuntimeException("Failed parsing JavaPath '"+path+"'",e);
        }
        LOG.debug("parsing of {} complete: {} found paths: {}",path,elements,visitor.pathNumber+1);
        return Collections.unmodifiableList(elements);
    }

    private static StringReader r(String s) {
        StringReader sr = new StringReader(s);
        return sr;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy