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

org.codehaus.jettison.util.StringIndenter Maven / Gradle / Ivy

There is a newer version: 1.5.4
Show newest version
/**
 * Licensed 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.codehaus.jettison.util;

/**
 * 
 * indent json, assumes the input is not yet indented.  here is an example:
 * {
 * "FastResponseJs":{
 *   "ajaxElements":{
 *     "AjaxMapEntry":[
 *       {
 *         "theKey":{
 *           "@class":"string",
 *           "$":"ajax1a"
 *         },
 *         "theValue":{
 *           "@class":"AjaxEvent",
 *           "ajaxSendFormNames":{
 *             "string":"ajax1"
 *           },
 *           "ajaxEventType":"NORMAL",
 *           "eventName":"onblur",
 *           "ajaxId":"PRLZY5QZ",
 *           "screenElementId":"ajax1a",
 *           "asynchronous":true,
 *           "disableValidation":true
 *         }
 *         
 *       },
 *       {
 *         "theKey":{
 *        ...
 *        
 *        
 *   Usage: String formatted = new StringIndenter(jsonString).result();
 * 
*/ public class StringIndenter { /** chars to process */ private String json; /** current start tag */ private int startTagIndex; /** current end tag */ private int endTagIndex; /** current number of indents (times to is the indent */ private int currentNumberOfIndents; /** result */ private StringBuilder result; /** * get the result * @return the result */ public String result() { try { this.indent(); } catch (RuntimeException re) { throw new RuntimeException("Problem here: " + this, re); } if (this.json == null) { return null; } String resultString = this.result.toString(); return resultString == null ? null : resultString.trim(); } /** * indent the string */ private void indent() { if (this.json == null) { return; } this.result = new StringBuilder(); this.startTagIndex = -1; this.endTagIndex = -1; this.currentNumberOfIndents = 0; //{ // "a":{ // "b\"b":{ // "c\\":"d" // }, // "e":"f", // "g":[ // "h":"i" // ] // } //} while(true) { this.startTagIndex = findStartTagIndex(); if (this.startTagIndex == -1) { //cant find anything else... make sure everything there if (this.endTagIndex != this.json.length()-1) { this.result.append(this.json, this.endTagIndex+1, this.json.length()); } break; } //handles first tag if (instantIndent(this.json, this.startTagIndex)) { this.currentNumberOfIndents++; this.printNewlineIndent(this.startTagIndex, this.startTagIndex+1); this.endTagIndex = this.startTagIndex; continue; } //handles end of associative array with comma if (instantUnindentTwoChars(this.json, this.startTagIndex)) { this.currentNumberOfIndents--; //this is on a line by itself this.newlineIndent(); this.printNewlineIndent(this.startTagIndex, this.startTagIndex+2); this.endTagIndex = this.startTagIndex+1; continue; } //handles end of array with comma if (instantUnindent(this.json, this.startTagIndex)) { this.currentNumberOfIndents--; if (onNewline()) { this.unindent(); } else { this.newlineIndent(); } this.printNewlineIndent(this.startTagIndex, this.startTagIndex+1); this.endTagIndex = this.startTagIndex; continue; } //handles end of array with comma if (instantNewline(this.json, this.startTagIndex)) { this.printNewlineIndent(this.startTagIndex, this.startTagIndex+1); this.endTagIndex = this.startTagIndex; continue; } this.endTagIndex = findEndTagIndex(); //one thing's for sure, we are printing out this tag this.result.append(this.json, this.startTagIndex, this.endTagIndex+1); //go back to top to end if (this.endTagIndex >= this.json.length()-1) { continue; } char nextChar = this.json.charAt(this.endTagIndex+1); //if next is colon, print that out too if (nextChar == ':') { this.result.append(':'); this.endTagIndex++; } //ready to loop around... } } /** * see if current pos is on newline * @return true if on new line */ private boolean onNewline() { for (int i=this.result.length()-1;i>=0;i--) { char curChar = this.result.charAt(i); if (curChar == '\n') { return true; } if (Character.isWhitespace(curChar)) { continue; } //if not whitespace, then not on own line return false; } //i guess first line is new line return true; } /** * see if instant indent * @param json * @param index * @return if it is an instant indent */ private static boolean instantIndent(String json, int index) { char curChar = json.charAt(index); if (curChar == '{' || curChar == '[') { return true; } return false; } /** * see if instant indent * @param json * @param index * @return if it is an instant indent */ private static boolean instantNewline(String json, int index) { char curChar = json.charAt(index); if (curChar == ',') { return true; } return false; } /** * see if instant unindent * @param json * @param index * @return if it is an instant unindent */ private static boolean instantUnindent(String json, int index) { char curChar = json.charAt(index); if (curChar == '}' || curChar == ']') { return true; } return false; } /** * see if instant indent * @param json * @param index * @return if it is an instant indent */ private static boolean instantUnindentTwoChars(String json, int index) { char curChar = json.charAt(index); if (index == json.length()-1) { return false; } char nextchar = json.charAt(index+1); if (curChar == '}' && nextchar == ',') { return true; } return false; } /** * put a newline and indent * @param start * @param end */ private void printNewlineIndent(int start, int end) { //lets put this tag on the queue this.result.append(this.json, start, end); this.newlineIndent(); } /** * put a newline and indent */ private void newlineIndent() { this.result.append("\n").append(repeat(" ", this.currentNumberOfIndents)); } /** * repeat a string a certain number of times. * @param theString * @param times * @return the string */ private static String repeat(String theString, int times) { StringBuffer result = new StringBuffer(); //loop through, keep appending for (int i = 0; i < times; i++) { result.append(theString); } return result.toString(); } /** * unindent a previous indent if it is there */ private void unindent() { for (int i=0;i<2;i++) { if (this.result.charAt(this.result.length()-1) == ' ') { this.result.deleteCharAt(this.result.length()-1); } } } /** * after the last end tag, find the next start tag * @return the next start tag */ private int findStartTagIndex() { return findNextStartTagIndex(this.json, this.endTagIndex+1); } /** * after the last start tag, find the next end start tag * @return the next start tag */ private int findEndTagIndex() { return findNextEndTagIndex(this.json, this.startTagIndex+1); } /** * find the start tag from json and a start from index * either look for a quote, {, [ or scalar. generally not whitespace * @param json * @param startFrom * @return the start tag index of -1 if not found another */ private static int findNextStartTagIndex(String json, int startFrom) { int length = json.length(); for (int i= startFrom; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy