NodenamePredicateEvaluator.java 5.11 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.Node
 *  javax.jcr.RepositoryException
 *  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 com.day.cq.search.facets.Bucket;
import com.day.cq.search.facets.Facet;
import com.day.cq.search.facets.FacetExtractor;
import com.day.cq.search.facets.buckets.SimpleBucket;
import com.day.cq.search.facets.extractors.FacetImpl;
import com.day.cq.search.impl.util.GlobPatternUtil;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
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/nodename")
public class NodenamePredicateEvaluator
extends AbstractPredicateEvaluator {
    public static final String NODENAME = "nodename";

    @Override
    public String getXPathExpression(Predicate p, EvaluationContext context) {
        if (!p.hasNonEmptyValue("nodename")) {
            return null;
        }
        String name = p.get("nodename");
        if (this.containsWildcard(name)) {
            if (this.containsWildcardsNotSupportedWithJcrLike(name)) {
                return null;
            }
            return "jcr:like(fn:name(), '" + this.convertWildcardsForJcrLike(name) + "')";
        }
        return "fn:name() = '" + ISO9075.encode((String)name) + "'";
    }

    @Override
    public boolean includes(Predicate p, Row row, EvaluationContext context) {
        if (!p.hasNonEmptyValue("nodename")) {
            return true;
        }
        String path = context.getPath(row);
        if (path != null) {
            return Pattern.matches(GlobPatternUtil.convertWildcardToRegex(p.get("nodename")), Text.getName((String)path));
        }
        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 Text.getName((String)path1).compareTo(Text.getName((String)path2));
            }
        };
    }

    @Deprecated
    protected boolean containsWildcard(Predicate p) {
        return this.containsWildcard(p.get("nodename"));
    }

    protected boolean containsWildcard(String name) {
        for (int i = 0; i < name.length(); ++i) {
            if ("*?[]".indexOf(name.charAt(i)) == -1) continue;
            return true;
        }
        return false;
    }

    protected boolean containsWildcardsNotSupportedWithJcrLike(String name) {
        return name.indexOf(91) >= 0 || name.indexOf(93) >= 0;
    }

    private String convertWildcardsForJcrLike(String term) {
        return term.replace('*', '%').replace('?', '_');
    }

    @Override
    public boolean canXpath(Predicate p, EvaluationContext context) {
        if (p.hasNonEmptyValue("nodename")) {
            return !this.containsWildcard(p.get("nodename"));
        }
        return true;
    }

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

    @Override
    public FacetExtractor getFacetExtractor(Predicate predicate, EvaluationContext context) {
        return new NodenameFacetExtractor(predicate.clone());
    }

    private static class NodenameFacetExtractor
    implements FacetExtractor {
        private Map<String, SimpleBucket> nameBuckets = new HashMap<String, SimpleBucket>();
        private Predicate predicateTemplate;

        public NodenameFacetExtractor(Predicate predicateTemplate) {
            this.predicateTemplate = predicateTemplate;
        }

        @Override
        public void handleNode(Node node) throws RepositoryException {
            String name = node.getName();
            SimpleBucket bucket = this.nameBuckets.get(name);
            if (bucket == null) {
                Predicate p = this.predicateTemplate.clone();
                p.set("nodename", name);
                bucket = new SimpleBucket(p, name);
                this.nameBuckets.put(name, bucket);
            }
            bucket.increment();
        }

        @Override
        public Facet getFacet() {
            return new FacetImpl(this.nameBuckets.values());
        }

        public boolean equals(Object obj) {
            return obj instanceof NodenameFacetExtractor;
        }

        public int hashCode() {
            return 1;
        }
    }

}