Package org.gridkit.jvmtool

Source Code of org.gridkit.jvmtool.StackFilterParser$LastNode

package org.gridkit.jvmtool;

import java.util.ArrayList;
import java.util.List;

import org.gridkit.jvmtool.StackTraceFilter.PatternElementMatcher;
import org.gridkit.jvmtool.StackTraceFilter.PositionalMatcher;

public abstract class StackFilterParser {

    public static final String D_REQUIRE = "REQUIRE";
    public static final String D_ANY = "ANY";
    public static final String D_LAST = "LAST";
    public static final String D_FOLLOWED = "FOLLOWED";
    public static final String D_NOT_FOLLOWED = "NOT FOLLOWED";

    public static StackFilterParser anyNode() {
        return new AnyNode();
    }

    public static StackFilterParser allNode() {
        return new AllNode();
    }

    public abstract StackTraceFilter getFilter();

    public static class AnyNode extends StackFilterParser {

        List<StackFilterParser> subnodes = new ArrayList<StackFilterParser>();

        @Cascade.Section
        public StackFilterParser child(String line) {
            if (line.startsWith("!")) {
                String dir = normalizeDirective(line);
                if (dir.equals(D_REQUIRE)) {
                    AllNode node = new AllNode();
                    subnodes.add(node);
                    return node;
                }
                else if (dir.equals(D_ANY)) {
                    AnyNode node = new AnyNode();
                    subnodes.add(node);
                    return node;
                }
                else if (dir.equals(D_LAST)) {
                    LastNode node = new LastNode();
                    subnodes.add(node);
                    return node;
                }
                else {
                    throw new IllegalArgumentException("Enexpected directive: " + dir);
                }
            }
            else {
                LiteralNode node = new LiteralNode(line);
                subnodes.add(node);
                return node;
            }
        }

        @Override
        public StackTraceFilter getFilter() {
            StackTraceFilter[] filters = new StackTraceFilter[subnodes.size()];
            int n = 0;
            for(StackFilterParser s: subnodes) {
                filters[n++] = s.getFilter();
            }
            return new StackTraceFilter.AnyMatcher(filters);
        }
    }

    public static class AllNode extends AnyNode {

        @Override
        public StackTraceFilter getFilter() {
            StackTraceFilter[] filters = new StackTraceFilter[subnodes.size()];
            int n = 0;
            for(StackFilterParser s: subnodes) {
                filters[n++] = s.getFilter();
            }
            return new StackTraceFilter.RequiredMatcher(filters);
        }
    }

    public static class LiteralNode extends StackFilterParser {

        String line;

        public LiteralNode(String line) {
            this.line = line;
        }

        @Cascade.Section
        public StackFilterParser child(String line) {
            if (line.startsWith("!")) {
                String dir = normalizeDirective(line);
                throw new IllegalArgumentException("Enexpected directive: " + dir);
            }
            else {
                throw new IllegalArgumentException("Enexpected nested line: " + line);
            }
        }

        @Override
        public StackTraceFilter getFilter() {
            final PatternElementMatcher matcher = new PatternElementMatcher(line);
            return new StackTraceFilter.HasElementMatcher(matcher);
        }
    }

    public static class LastNode extends StackFilterParser {

        List<String> targets = new ArrayList<String>();
        StackFilterParser predicate;
        boolean notMode;
        boolean directFollow;

        @Cascade.Section
        public StackFilterParser child(String line) {
            if (line.startsWith("!")) {
                String dir = normalizeDirective(line);

                if (predicate != null) {
                    throw new IllegalArgumentException("Could be only one directive");
                }
                if (targets.isEmpty()) {
                    throw new IllegalArgumentException("Matcher is required");
                }

                if (dir.equals(D_FOLLOWED)) {
                    directFollow = true;
                    return predicate = new AnyNode();
                }
                else if (dir.equals(D_NOT_FOLLOWED)) {
                    directFollow = true;
                    notMode = true;
                    return predicate = new AnyNode();
                }
                else {
                    throw new IllegalArgumentException("Enexpected directive: " + dir);
                }
            }
            else {
                if (predicate != null) {
                    throw new IllegalArgumentException("Should be no nested line after predicate directive");
                }
                targets.add(line);
                return null;
            }
        }

        @Override
        public StackTraceFilter getFilter() {
            if (predicate == null) {
                throw new IllegalArgumentException("!LAST statement is missing predicate");
            }
            if (targets.isEmpty()) {
                throw new IllegalArgumentException("!LAST statement is missing filter");
            }

            String[] m = targets.toArray(new String[targets.size()]);

            StackTraceFilter p = predicate.getFilter();
            if (notMode) {
                final StackTraceFilter nested = p;
                p = new StackTraceFilter() {
                    @Override
                    public boolean evaluate(StackTraceElement[] trace) {
                        return !nested.evaluate(trace);
                    }

                };
            }

            PatternElementMatcher matcher = new PatternElementMatcher(m);

            PositionalMatcher pm = new PositionalMatcher();
            pm.topDown = true;
            pm.lastOnly = true;
            pm.singleElementPredicate = directFollow;
            pm.targetElementMatcher = matcher;
            pm.predicate = p;

            return pm;
        }
    }

    static String normalizeDirective(String line) {
        return line.substring(1).replace("\\s+", " ").toUpperCase().trim();
    }
}
TOP

Related Classes of org.gridkit.jvmtool.StackFilterParser$LastNode

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
script>