Package com.browseengine.bobo.service.util

Source Code of com.browseengine.bobo.service.util.BoboJSONStreamWriter$Node

package com.browseengine.bobo.service.util;

import com.thoughtworks.xstream.core.util.FastStack;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriter;

import java.io.Writer;
import java.util.Collection;

/**
* A simple writer that outputs JSON in a pretty-printed indented stream.
* Arrays, Lists and Sets rely on you NOT using XStream.addImplicitCollection(..)
*
* @author Paul Hammant
* @author John Wang fixed streaming for other primitive types
* @since 1.2
*/
public class BoboJSONStreamWriter implements ExtendedHierarchicalStreamWriter {

    private final QuickWriter writer;
    private final FastStack elementStack = new FastStack(16);
    private final char[] lineIndenter;

    private int depth;
    private boolean readyForNewLine;
    private boolean tagIsEmpty;
    private String newLine;


    public BoboJSONStreamWriter(Writer writer, char[] lineIndenter, String newLine) {
        this.writer = new QuickWriter(writer);
        this.lineIndenter = lineIndenter;
        this.newLine = newLine;
    }

    public BoboJSONStreamWriter(Writer writer, char[] lineIndenter) {
        this(writer, lineIndenter, "\n");
    }

    public BoboJSONStreamWriter(Writer writer, String lineIndenter, String newLine) {
        this(writer, lineIndenter.toCharArray(), newLine);
    }

    public BoboJSONStreamWriter(Writer writer, String lineIndenter) {
        this(writer, lineIndenter.toCharArray());
    }

    public BoboJSONStreamWriter(Writer writer) {
        this(writer, new char[]{' ', ' '});
    }

    /**
     *
     * @deprecated Use startNode(String name, Class clazz) instead.
     */

    public void startNode(String name) {
        startNode(name, null);
    }

    public void startNode(String name, Class clazz) {
        Node currNode = (Node) elementStack.peek();
        if (currNode == null) {
            writer.write("{");
        }
        if (currNode != null && currNode.fieldAlready) {
            writer.write(",");
        }
        tagIsEmpty = false;
        finishTag();
        if (currNode == null
                || (currNode.clazz != null
                        && Collection.class.isAssignableFrom(currNode.clazz) == false
                        && currNode.clazz.isArray() == false)) {
            writer.write("\"");
            writer.write(name);
            writer.write("\": ");
        }
        if (clazz != null &&
                (Collection.class.isAssignableFrom(clazz) || clazz.isArray())) {
            writer.write("[");
        } else if (hasChildren(clazz)) {
            writer.write("{");
        }
        if (currNode != null) {
            currNode.fieldAlready = true;
        }
        elementStack.push(new Node(name, clazz));
        depth++;
        readyForNewLine = true;
        tagIsEmpty = true;
    }

    public class Node {
        public final String name;
        public final Class clazz;
        public boolean fieldAlready;
        public Node(String name, Class clazz) {
            this.name = name;
            this.clazz = clazz;
        }
    }

    public void setValue(String text) {
        readyForNewLine = false;
        tagIsEmpty = false;
        finishTag();
        writeText(writer, text);
    }

    public void addAttribute(String key, String value) {
        writer.write(" \"");
        writer.write(key);
        writer.write("\" :");
        writeAttributeValue(writer, value);
        writer.write('\"');
    }

    protected void writeAttributeValue(QuickWriter writer, String text) {
        writeText(text, null);
    }

    protected void writeText(QuickWriter writer, String text) {
        Node foo = (Node) elementStack.peek();

        writeText(text, foo.clazz);
    }

    private void writeText(String text, Class clazz) {
        if (needsQuotes(clazz)) {
            writer.write("\"");
        }

        int i = 0;
        while(true) {
            int idxQuote = text.indexOf('"', i);
            int idxSlash = text.indexOf('\\', i);
            int idx = Math.min(
                idxQuote < 0 ? Integer.MAX_VALUE : idxQuote,
                idxSlash < 0 ? Integer.MAX_VALUE : idxSlash);
            if (idx == Integer.MAX_VALUE) {
                break;
            }
            if (idx != 0) {
                this.writer.write(text.substring(i, idx));
            }
            if (idx == idxQuote) {
                this.writer.write("\\\"");
            } else {
                this.writer.write("\\\\");
            }
            i = idx+1;
        }
       
        this.writer.write(text.substring(i));
        if (needsQuotes(clazz)) {
            writer.write("\"");
        }
    }

    private boolean needsQuotes(Class clazz) {
        if (clazz == Integer.TYPE || clazz == Integer.class) {
            return false;
        }
        if (clazz == Boolean.TYPE || clazz == Boolean.class) {
            return false;
        }
        if (clazz == Short.TYPE || clazz == Short.class) {
            return false;
        }
        if (clazz == Long.TYPE || clazz == Long.class) {
            return false;
        }
        if (clazz == Float.TYPE || clazz == Float.class) {
            return false;
        }
        if (clazz == Double.TYPE || clazz == Double.class) {
            return false;
        }
        if (clazz == Byte.TYPE || clazz == Byte.class) {
            return false;
        }
        if (clazz == Character.TYPE || clazz == Character.class) {
            return false;
        }
       
       
        if (clazz.isPrimitive()){
          return false;
        }
        if (clazz.isEnum()){
          return false;
        }
       
        return true;
    }

    public void endNode() {
        depth--;
        Node node = (Node) elementStack.pop();
        if (tagIsEmpty && !hasChildren(node.clazz)) {
            readyForNewLine = false;
            finishTag();
        } else {
            finishTag();
            if (node.clazz != null &&
                    (Collection.class.isAssignableFrom(node.clazz) || node.clazz.isArray())) {
                writer.write("]");
            } else if (hasChildren(node.clazz)) {
                writer.write("}");
            }
        }
        readyForNewLine = true;
        if (depth == 0 ) {
            writer.write("}");
            writer.flush();
        }
    }

    private boolean hasChildren(Class clazz) {
        if (clazz == String.class) {
            return false;
        } else {
            return needsQuotes(clazz);
        }
    }

    private void finishTag() {
        if (readyForNewLine) {
            endOfLine();
        }
        readyForNewLine = false;
        tagIsEmpty = false;
    }

    protected void endOfLine() {
        writer.write(newLine);
        for (int i = 0; i < depth; i++) {
            writer.write(lineIndenter);
        }
    }

    public void flush() {
        writer.flush();
    }

    public void close() {
        writer.close();
    }

    public HierarchicalStreamWriter underlyingWriter() {
        return this;
    }
}
TOP

Related Classes of com.browseengine.bobo.service.util.BoboJSONStreamWriter$Node

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.