PathPredicateEvaluator.java 5.02 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.query.Row
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.jackrabbit.util.ISO9075
 *  org.apache.jackrabbit.util.Text
 */
package com.day.cq.search.eval;

import com.day.cq.search.Predicate;
import com.day.cq.search.eval.AbstractPredicateEvaluator;
import com.day.cq.search.eval.EvaluationContext;
import java.util.Comparator;
import javax.jcr.query.Row;
import org.apache.felix.scr.annotations.Component;
import org.apache.jackrabbit.util.ISO9075;
import org.apache.jackrabbit.util.Text;

@Component(metatype=0, factory="com.day.cq.search.eval.PredicateEvaluator/path")
public class PathPredicateEvaluator
extends AbstractPredicateEvaluator {
    public static final String PATH = "path";
    public static final String EXACT = "exact";
    public static final String FLAT = "flat";
    public static final String SELF = "self";

    public static String encodePath(Predicate p) {
        if (!p.hasNonEmptyValue("path")) {
            return "";
        }
        String path = p.get("path");
        if (p.getBool("exact") && PathPredicateEvaluator.containsWildcard(path)) {
            if (path.startsWith("/")) {
                path = path.substring(1);
            }
            StringBuilder builder = new StringBuilder();
            for (String name : Text.explode((String)path, (int)47, (boolean)true)) {
                builder.append("/");
                if (name.length() == 0) continue;
                if ("*".equals(name)) {
                    builder.append("*");
                    continue;
                }
                builder.append(ISO9075.encode((String)name));
            }
            return builder.toString();
        }
        return ISO9075.encodePath((String)path);
    }

    private static boolean containsWildcard(String s) {
        return s.indexOf(42) >= 0;
    }

    private static boolean match(String pattern, String s) {
        return PathPredicateEvaluator.recurseMatchPattern(pattern, s, 0, 0);
    }

    private static boolean recurseMatchPattern(String pattern, String s, int sIdx, int pIdx) {
        int pLen = pattern.length();
        int sLen = s.length();
        while (pIdx < pLen) {
            if (sIdx >= sLen && pattern.charAt(pIdx) != '*') {
                return false;
            }
            if (pattern.charAt(pIdx) == '*') {
                while (sIdx < sLen && s.charAt(sIdx) != '/') {
                    ++sIdx;
                }
                return PathPredicateEvaluator.recurseMatchPattern(pattern, s, sIdx, ++pIdx);
            }
            if (pattern.charAt(pIdx) == '\\' && ++pIdx >= pLen) {
                return false;
            }
            if (pIdx < pLen && sIdx < sLen && pattern.charAt(pIdx) != s.charAt(sIdx)) {
                return false;
            }
            ++pIdx;
            ++sIdx;
        }
        return sIdx >= sLen;
    }

    @Override
    public String getXPathExpression(Predicate p, EvaluationContext context) {
        return null;
    }

    @Override
    public boolean includes(Predicate p, Row row, EvaluationContext context) {
        if (!p.hasNonEmptyValue("path")) {
            return true;
        }
        String path = context.getPath(row);
        if (path != null) {
            String pattern = p.get("path");
            if (p.getBool("exact")) {
                if (pattern.endsWith("/")) {
                    pattern = pattern.substring(0, pattern.length() - 1);
                }
                if (PathPredicateEvaluator.containsWildcard(pattern)) {
                    return PathPredicateEvaluator.match(pattern, path);
                }
                return path.equals(pattern);
            }
            pattern = pattern.replaceAll("//", "/");
            if (p.getBool("flat")) {
                if (pattern.endsWith("/")) {
                    return path.matches(pattern + "[^/]+");
                }
                return path.matches(pattern + "/[^/]+");
            }
            if (p.getBool("self")) {
                return path.startsWith(pattern);
            }
            if (path.equals(pattern)) {
                return false;
            }
            return path.startsWith(pattern + "/");
        }
        return false;
    }

    @Override
    public Comparator<Row> getOrderByComparator(Predicate predicate, final EvaluationContext context) {
        return new Comparator<Row>(){

            @Override
            public int compare(Row r1, Row r2) {
                String path1 = context.getPath(r1);
                if (path1 == null) {
                    return 0;
                }
                String path2 = context.getPath(r2);
                if (path2 == null) {
                    return 0;
                }
                return path1.compareTo(path2);
            }
        };
    }

    @Override
    public boolean canXpath(Predicate predicate, EvaluationContext context) {
        return false;
    }

    @Override
    public boolean canFilter(Predicate predicate, EvaluationContext context) {
        return true;
    }

}