com.day.cq.search.writer.SelectivePropHitWriter Maven / Gradle / Ivy
/*
* Copyright 1997-2010 Day Management AG
* Barfuesserplatz 6, 4001 Basel, Switzerland
* All Rights Reserved.
*
* This software is the confidential and proprietary information of
* Day Management AG, ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Day.
*/
package com.day.cq.search.writer;
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;
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.Query;
import com.day.cq.search.result.Hit;
/**
* {@linkplain SelectivePropHitWriter} writes selective node properties.
* To write selective property of child nodes,specify relative path of property.
*/
@Component(metatype = false, factory = "com.day.cq.search.writer.ResultHitWriter/selective")
public class SelectivePropHitWriter implements ResultHitWriter {
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(hit.getPath());
} else if (resultNode.hasProperty(name)) {
w.writeProp(writer, resultNode.getProperty(name));
}
}
for (Map.Entry entry : ps.getChildPropSpeciferMap().entrySet()) {
String nodeName = entry.getKey();
if (resultNode.hasNode(nodeName)) {
w.dump(resultNode.getNode(nodeName), writer, entry.getValue());
}
}
}
static class NodeWriter extends JsonItemWriter {
NodeWriter() {
super(null);
}
public void writeProp(JSONWriter writer, Property prop) throws RepositoryException, JSONException {
this.writeProperty(writer, prop);
}
/** Dump given node in JSON in recursive fashion, along with the selected properties. */
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)) {
Property prop = node.getProperty(propName);
writeProperty(w, prop);
}
}
for (Map.Entry entry : ps.getChildPropSpeciferMap().entrySet()) {
String nodeName = entry.getKey();
if (node.hasNode(nodeName)) {
dump(node.getNode(nodeName), w, entry.getValue());
}
}
w.endObject();
}
}
/**
* Class that specify properties at first level and properties of child nodes.
*/
private static class PropertySpecifier {
/**
* set of first level properties
*/
private Set propSet = new HashSet();
/**
* map to hold PropertySpecifier of child nodes.
*/
private Map childPropSpeciferMap = new HashMap();
private void addProp(String propName) {
propSet.add(propName);
}
private void addChildSpecifer(String childName, PropertySpecifier ps) {
childPropSpeciferMap.put(childName, ps);
}
private PropertySpecifier getChildSpecifer(String childName) {
return childPropSpeciferMap.get(childName);
}
public Set getPropSet() {
return propSet;
}
public Map getChildPropSpeciferMap() {
return childPropSpeciferMap;
}
@Override
public String toString() {
return propSet.toString() + childPropSpeciferMap.toString();
}
/**
* Parse properties string to PropertySpecier.
*
* @param properties whitespace separated properties name.
* @return
*/
public static PropertySpecifier parsePropertyString(String properties) {
PropertySpecifier ps = new PropertySpecifier();
String props[] = properties.split(" ");
for (String propName : props) {
propName = propName.trim();
if ("".equals(propName)) continue;
String[] tokens = propName.split("/");
if (tokens.length == 1) {
ps.addProp(tokens[0]);
} else {
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;
}
}
}