All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.cq.extwidget.ExtTreeJsonWriter Maven / Gradle / Ivy

There is a newer version: 6.5.21
Show newest version
/*
 * 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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy