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

org.apache.sling.commons.json.jcr.JsonItemWriter Maven / Gradle / Ivy

There is a newer version: 6.5.21
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.sling.commons.json.jcr;

import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.Set;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;

import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.io.JSONWriter;

/**
 * Dumps JCR Items as JSON data. The dump methods are threadsafe.
 */
@Deprecated
public class JsonItemWriter {

    private static DateFormat calendarFormat;

    private final Set propertyNamesToIgnore;
    
    /** Used to format date values */
    public static final String ECMA_DATE_FORMAT = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z";
    
    /** Used to format date values */
    public static final Locale DATE_FORMAT_LOCALE = Locale.US;


    /**
     * Create a JsonItemWriter
     * 
     * @param propertyNamesToIgnore if not null, a property having a name from
     *            this set of values is ignored. TODO we should use a filtering
     *            interface to make the selection of which Nodes and Properties
     *            to dump more flexible.
     */
    public JsonItemWriter(Set propertyNamesToIgnore) {
        this.propertyNamesToIgnore = propertyNamesToIgnore;
    }

    /**
     * Dump all Nodes of given NodeIterator in JSON
     * 
     * @throws JSONException
     */
    public void dump(NodeIterator it, Writer out) throws RepositoryException,
            JSONException {
        final JSONWriter w = new JSONWriter(out);
        w.array();
        while (it.hasNext()) {
            dump(it.nextNode(), w, 1, 1);
        }
        w.endArray();
    }

    /** Dump given node in JSON, optionally recursing into its child nodes */
    public void dump(Node node, Writer w, int maxRecursionLevels)
            throws RepositoryException, JSONException {
        dump(node, w, maxRecursionLevels, false);
    }

    /**
     * Dump given node in JSON, optionally recursing into its child nodes
     * @param tidy if true the json dump is nicely formatted
     */
    public void dump(Node node, Writer w, int maxRecursionLevels, boolean tidy)
            throws RepositoryException, JSONException {
        JSONWriter jw = new JSONWriter(w);
        jw.setTidy(tidy);
        dump(node, jw, 0, maxRecursionLevels);
    }

    /** Dump given property in JSON */
    public void dump(Property p, Writer w) throws JSONException,
            ValueFormatException, RepositoryException {
        final JSONWriter jw = new JSONWriter(w);
        jw.object();
        writeProperty(jw, p);
        jw.endObject();
    }

    /** Dump given node in JSON, optionally recursing into its child nodes */
    protected void dump(Node node, JSONWriter w, int currentRecursionLevel,
            int maxRecursionLevels) throws RepositoryException, JSONException {

        w.object();
        PropertyIterator props = node.getProperties();

        // the node's actual properties
        while (props.hasNext()) {
            Property prop = props.nextProperty();

            if (propertyNamesToIgnore != null
                && propertyNamesToIgnore.contains(prop.getName())) {
                continue;
            }

            writeProperty(w, prop);
        }

        // the child nodes
        if (recursionLevelActive(currentRecursionLevel, maxRecursionLevels)) {
            final NodeIterator children = node.getNodes();
            while (children.hasNext()) {
                final Node n = children.nextNode();
                dumpSingleNode(n, w, currentRecursionLevel, maxRecursionLevels);
            }
        }

        w.endObject();
    }

    /** Dump a single node */
    protected void dumpSingleNode(Node n, JSONWriter w,
            int currentRecursionLevel, int maxRecursionLevels)
            throws RepositoryException, JSONException {
        if (recursionLevelActive(currentRecursionLevel, maxRecursionLevels)) {
            w.key(n.getName());
            dump(n, w, currentRecursionLevel + 1, maxRecursionLevels);
        }
    }

    /** true if the current recursion level is active */
    protected boolean recursionLevelActive(int currentRecursionLevel,
            int maxRecursionLevels) {
        return maxRecursionLevels < 0
            || currentRecursionLevel < maxRecursionLevels;
    }

    /**
     * Write a single property
     */
    protected void writeProperty(JSONWriter w, Property p)
            throws ValueFormatException, RepositoryException, JSONException {
        // special handling for binaries: we dump the length and not the length
        if (p.getType() == PropertyType.BINARY) {
            // TODO for now we mark binary properties with an initial colon in
            // their name
            // (colon is not allowed as a JCR property name)
            // in the name, and the value should be the size of the binary data
            w.key(":" + p.getName());
            if (!p.isMultiple()) {
                w.value(p.getLength());
            } else {
                final long[] sizes = p.getLengths();
                w.array();
                for (int i = 0; i < sizes.length; i++) {
                    w.value(sizes[i]);
                }
                w.endArray();
            }
            return;
        }
        w.key(p.getName());

        if (!p.isMultiple()) {
            dumpValue(w, p.getValue());
        } else {
            w.array();
            for (Value v : p.getValues()) {
                dumpValue(w, v);
            }
            w.endArray();
        }
    }

    /**
     * Writes the given value to the JSON writer. currently the following
     * conversions are done: 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
     * 
JSR Property TypeJSON Value Type
BINARYalways 0 as long
DATEconverted date string as defined by ECMA
BOOLEANboolean
LONGlong
DOUBLEdouble
all other * string
1 Currently not implemented and uses 0 as default. * * @param w json writer * @param v value to dump */ protected void dumpValue(JSONWriter w, Value v) throws ValueFormatException, IllegalStateException, RepositoryException, JSONException { switch (v.getType()) { case PropertyType.BINARY: w.value(0); break; case PropertyType.DATE: w.value(format(v.getDate())); break; case PropertyType.BOOLEAN: w.value(v.getBoolean()); break; case PropertyType.LONG: w.value(v.getLong()); break; case PropertyType.DOUBLE: w.value(v.getDouble()); break; default: w.value(v.getString()); } } public static synchronized String format(Calendar date) { if (calendarFormat == null) { calendarFormat = new SimpleDateFormat(ECMA_DATE_FORMAT, DATE_FORMAT_LOCALE); } return calendarFormat.format(date.getTime()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy