com.day.cq.extwidget.ExtTreeJsonWriter Maven / Gradle / Ivy
/*
* Copyright 1997-2008 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.extwidget;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Collections;
import java.util.Comparator;
import com.day.cq.commons.LabeledResource;
import com.day.cq.commons.TidyJSONWriter;
import org.apache.commons.collections.Predicate;
import com.day.text.Text;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.io.JSONWriter;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
/**
* Writes a resource tree in JSON format. This tree can be used by the
* EXT tree loader.
*/
public class ExtTreeJsonWriter {
/**
* internal resource resolver
*/
private final ResourceResolver resolver;
/**
* predicate to apply on the resources
*/
private final Predicate predicate;
/**
* maximum depth of the export
*/
private final int depth;
/**
* indicates if JSON export should be nicely formatted
*/
private boolean tidy;
/**
* Creates a new EXT tree json writer
*
* @param resolver resource resolver
* @param predicate predicate
* @param depth maximal depth
*/
public ExtTreeJsonWriter(ResourceResolver resolver, Predicate predicate,
int depth) {
this.resolver = resolver;
this.predicate = predicate;
this.depth = depth;
}
/**
* Checks the tidy flag.
* @return true
if export is tidy.
*/
public boolean isTidy() {
return tidy;
}
/**
* Controls if the export should be nicely formatted.
* @param tidy set to true
for tidy.
*/
public void setTidy(boolean tidy) {
this.tidy = tidy;
}
/**
* Write the resource tree starting at path
to the given writer.
* @param out writer
* @param path start path
* @throws IOException if an I/O error occurs
*/
public void write(Writer out, String path) throws IOException {
write(out, resolver.getResource(path));
}
/**
* Write the given resource tree to the given writer.
* @param out writer
* @param res start resource
* @throws IOException if an I/O error occurs
*/
public void write(Writer out, Resource res) throws IOException {
try {
TidyJSONWriter jw = new TidyJSONWriter(out);
jw.setTidy(tidy);
if (res == null) {
jw.array();
jw.endArray();
return;
}
boolean isOrderable = getIsOrderable(res);
write(jw, getChildren(res), 0, isOrderable);
} catch (JSONException e) {
throw new IOException("Error while writing json " + e);
}
}
/**
* Write the given resource list as JSON array to the output.
*
* @param out writer
* @param list list of resources
* @param level current level
* @throws JSONException if a JSON error occurs
*/
private void write(JSONWriter out, List list, int level, boolean orderable)
throws JSONException {
out.array();
List oList = orderable ? list : orderList(list);
for (Resource resource: oList) {
out.object();
LabeledResource lr = resource.adaptTo(LabeledResource.class);
String name = Text.getName(resource.getPath());
out.key("name").value(name);
String text;
if (lr == null) {
text = name;
} else {
text = (lr.getTitle() == null)
? name
: lr.getTitle();
if (lr.getDescription() != null) {
out.key("description").value(lr.getDescription());
}
}
if(text != null){
text = text.replaceAll("<","<");
}
out.key("text").value(text);
out.key("type").value(resource.getResourceType());
List children = getChildren(resource);
// write CSS class information according to presence of children.
// this should probably be done via the 'type' attribute above in
// the widget itself
out.key("cls").value(children.isEmpty() ? "file": "folder");
if (children.isEmpty()) {
out.key("leaf").value(true);
} else if (level < depth) {
out.key("children");
boolean isOrderable = getIsOrderable(resource);
write(out, children, level + 1, isOrderable);
}
out.endObject();
}
out.endArray();
}
/**
* Returns a list of child resources that match the internal predicate.
* @param res parent resource
* @return list of child resources
*/
private List getChildren(Resource res) {
List children = new LinkedList();
for (Iterator iter = resolver.listChildren(res); iter.hasNext();) {
Resource child = iter.next();
if (predicate == null || predicate.evaluate(child)) {
children.add(child);
}
}
return children;
}
private List orderList(List list) {
Collections.sort(list, new Comparator(){
public int compare(Object o1, Object o2) {
Resource r1 = (Resource) o1;
Resource r2 = (Resource) o2;
return Text.getName(r1.getPath()).compareToIgnoreCase(Text.getName(r2.getPath()));
}
});
return list;
}
private boolean getIsOrderable(Resource resource) {
Node node = resource.adaptTo(Node.class);
if (node != null) {
try {
return node.getPrimaryNodeType().hasOrderableChildNodes();
} catch (RepositoryException re) {}
}
return false;
}
}