com.conwet.xjsp.json.JSONUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.conwet.xjsp.json.JSONUtil.java

Source

package com.conwet.xjsp.json;

/*
 * #%L
 * eXtensible JSON Streaming Protocol
 * %%
 * Copyright (C) 2011 - 2014 CoNWeT Lab., Universidad Politcnica de Madrid
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */

import org.json.simple.parser.ParseException;

/**
 * Utility methods for working with Simple JSON objects.
 * @author sortega
 */
public class JSONUtil {

    public static void discardSpaces(StringBuilder buffer) {
        while (buffer.length() > 0 && (isSpace(buffer.charAt(0)) || buffer.charAt(0) == ',')) {
            buffer.deleteCharAt(0);
        }
    }

    /**
     * Extracts from the buffer a whole stanza or an stream finalizer "]}".
     * The recognized text is removed from the buffer.
     * 
     * Stanza recognition is implemented as a FSM. States:
     * <ul>
     *      <li>0. starting</li>
     *      <li>1. accepting text</li>
     *      <li>2. within an string</li>
     *      <li>3. finalizer</li>
     * </ul>
     * 
     * <img src="../../../../../resources/fsm.png"/>
     * 
     * @return Recognized text or <code>null</code>
     */
    public static String extractStanza(StringBuilder buffer) throws ParseException {
        discardSpaces(buffer);

        int state = 0;
        int pos = 0;
        int level = 1;

        while (pos < buffer.length()) {
            char c = buffer.charAt(pos);
            switch (state) {
            case 0:
                switch (c) {
                case '{':
                    state = 1;
                    break;
                case ']':
                    state = 3;
                    break;
                default:
                    throw new ParseException(ParseException.ERROR_UNEXPECTED_CHAR);
                }
                break;

            case 1:
                switch (c) {
                case '{':
                    level++;
                    break;
                case '}':
                    level--;
                    if (level == 0) {
                        String stanza = buffer.substring(0, pos + 1);
                        buffer.replace(0, pos + 1, "");
                        return stanza;
                    }
                    break;

                case '"':
                    state = 2;
                    break;

                default:
                    // nothing
                }
                break;

            case 2:
                switch (c) {
                case '\\':
                    pos++;
                    break;

                case '"':
                    state = 1;
                    break;

                default:
                    // nothing
                }
                break;

            case 3:
                if (isSpace(c)) {
                    pos++;
                } else if (c == '}') {
                    buffer.replace(0, pos + 1, "");
                    return "]}";
                }

            default:
                throw new IllegalStateException();
            }
            pos++;
        }

        return null;
    }

    public static boolean isSpace(char ch) {
        return Character.isSpaceChar(ch) || (ch == '\n') || (ch == '\r');
    }
}