SelectivePropHitWriter.java 5.12 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.Node
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.sling.commons.json.JSONException
 *  org.apache.sling.commons.json.io.JSONWriter
 *  org.apache.sling.commons.json.jcr.JsonItemWriter
 */
package com.day.cq.search.writer;

import com.day.cq.search.PredicateGroup;
import com.day.cq.search.Query;
import com.day.cq.search.result.Hit;
import com.day.cq.search.writer.ResultHitWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import org.apache.felix.scr.annotations.Component;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.io.JSONWriter;
import org.apache.sling.commons.json.jcr.JsonItemWriter;

@Component(metatype=0, factory="com.day.cq.search.writer.ResultHitWriter/selective")
public class SelectivePropHitWriter
implements ResultHitWriter {
    @Override
    public void write(Hit hit, JSONWriter writer, Query query) throws RepositoryException, JSONException {
        Node resultNode = hit.getNode();
        PredicateGroup rootPredicates = query.getPredicates();
        PropertySpecifier ps = PropertySpecifier.parsePropertyString(rootPredicates.get("properties", "jcr:path"));
        NodeWriter w = new NodeWriter();
        for (String name : ps.propSet) {
            if (name.equals("jcr:path")) {
                writer.key(name).value((Object)hit.getPath());
                continue;
            }
            if (!resultNode.hasProperty(name)) continue;
            w.writeProp(writer, resultNode.getProperty(name));
        }
        for (Map.Entry entry : ps.getChildPropSpeciferMap().entrySet()) {
            String nodeName = (String)entry.getKey();
            if (!resultNode.hasNode(nodeName)) continue;
            w.dump(resultNode.getNode(nodeName), writer, (PropertySpecifier)entry.getValue());
        }
    }

    private static class PropertySpecifier {
        private Set<String> propSet = new HashSet<String>();
        private Map<String, PropertySpecifier> childPropSpeciferMap = new HashMap<String, PropertySpecifier>();

        private PropertySpecifier() {
        }

        private void addProp(String propName) {
            this.propSet.add(propName);
        }

        private void addChildSpecifer(String childName, PropertySpecifier ps) {
            this.childPropSpeciferMap.put(childName, ps);
        }

        private PropertySpecifier getChildSpecifer(String childName) {
            return this.childPropSpeciferMap.get(childName);
        }

        public Set<String> getPropSet() {
            return this.propSet;
        }

        public Map<String, PropertySpecifier> getChildPropSpeciferMap() {
            return this.childPropSpeciferMap;
        }

        public String toString() {
            return this.propSet.toString() + this.childPropSpeciferMap.toString();
        }

        public static PropertySpecifier parsePropertyString(String properties) {
            String[] props;
            PropertySpecifier ps = new PropertySpecifier();
            for (String propName : props = properties.split(" ")) {
                if ("".equals(propName = propName.trim())) continue;
                String[] tokens = propName.split("/");
                if (tokens.length == 1) {
                    ps.addProp(tokens[0]);
                    continue;
                }
                PropertySpecifier parentSpec = ps;
                for (int i = 0; i < tokens.length - 1; ++i) {
                    String token = tokens[i];
                    PropertySpecifier childSpec = parentSpec.getChildSpecifer(token);
                    if (childSpec == null) {
                        childSpec = new PropertySpecifier();
                        parentSpec.addChildSpecifer(token, childSpec);
                    }
                    parentSpec = childSpec;
                }
                parentSpec.addProp(tokens[tokens.length - 1]);
            }
            return ps;
        }
    }

    static class NodeWriter
    extends JsonItemWriter {
        NodeWriter() {
            super(null);
        }

        public void writeProp(JSONWriter writer, Property prop) throws RepositoryException, JSONException {
            this.writeProperty(writer, prop);
        }

        public void dump(Node node, JSONWriter w, PropertySpecifier ps) throws RepositoryException, JSONException {
            w.key(node.getName());
            w.object();
            for (String propName : ps.getPropSet()) {
                if (!node.hasProperty(propName)) continue;
                Property prop = node.getProperty(propName);
                this.writeProperty(w, prop);
            }
            for (Map.Entry entry : ps.getChildPropSpeciferMap().entrySet()) {
                String nodeName = (String)entry.getKey();
                if (!node.hasNode(nodeName)) continue;
                this.dump(node.getNode(nodeName), w, (PropertySpecifier)entry.getValue());
            }
            w.endObject();
        }
    }

}