Package org.sourceforge.jsonedit.core.outline

Source Code of org.sourceforge.jsonedit.core.outline.JsonTextOutlineParserException

package org.sourceforge.jsonedit.core.outline;

import static org.sourceforge.jsonedit.core.util.JsonCharUtility.a;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.closeCurly;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.closeSquare;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.colon;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.comma;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.e;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.eof;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.f;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.isClosed;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.isNotClosed;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.isNotWhiteSpace;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.l;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.minus;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.n;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.openCurly;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.openSquare;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.point;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.quote;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.r;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.s;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.slash;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.t;
import static org.sourceforge.jsonedit.core.util.JsonCharUtility.u;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.IDocument;
import org.sourceforge.jsonedit.core.outline.elements.JsonArray;
import org.sourceforge.jsonedit.core.outline.elements.JsonBoolean;
import org.sourceforge.jsonedit.core.outline.elements.JsonElement;
import org.sourceforge.jsonedit.core.outline.elements.JsonError;
import org.sourceforge.jsonedit.core.outline.elements.JsonNull;
import org.sourceforge.jsonedit.core.outline.elements.JsonNumber;
import org.sourceforge.jsonedit.core.outline.elements.JsonObject;
import org.sourceforge.jsonedit.core.outline.elements.JsonParent;
import org.sourceforge.jsonedit.core.outline.elements.JsonString;
import org.sourceforge.jsonedit.core.util.reader.JsonDocReader;
import org.sourceforge.jsonedit.core.util.reader.JsonReader;
import org.sourceforge.jsonedit.core.util.reader.JsonReaderException;

/**
* JsonTextOutlineParser parses the Json text and returns a tree structure
* representing the Json Text. Used by the outline view.
*
* @author Matt Garner
*
*/
public class JsonTextOutlineParser {

  private JsonReader parser;
 
  private JsonParent root;
 
  private JsonParent parent;
 
  private IDocument doc;
 
  /**
   * Constructor taking the document to parse.
   *
   * @param doc
   */
  public JsonTextOutlineParser(IDocument doc) {
    super();
    parser = new JsonDocReader(doc);
    this.doc = doc;
  }
 
  /**
   * Parses the text in the document returning a tree structure.
   * 
   * @return
   */
  public JsonParent parse() {
   
    //System.out.println("Parse Text");
    try {

      char current = parser.getNextClean();

      if (current == openCurly) {
        doJsonObject("", parser.getPosition());
      } else if (current == openSquare){
        doJsonArray("", parser.getPosition());
      } else {
        JsonError jsonError = new JsonError(parent, "JSON should begin with { or [");
        root = new JsonObject(parent, "");
        root.addChild(jsonError);
        throw new JsonTextOutlineParserException();
      }
     
    } catch (Exception e) {
      //JsonLog.logError("Read exception: ", e);
    }
   
    return root;
  }
 
  /**
   * Parse a Json Object.
   *
   * @param key
   * @param startPos
   * @throws JsonReaderException
   * @throws JsonTextOutlineParserException
   * @throws BadLocationException
   * @throws BadPositionCategoryException
   */
  private void doJsonObject(String key, int startPos) throws JsonReaderException, JsonTextOutlineParserException, BadLocationException, BadPositionCategoryException {
   
    JsonObject jsonObject = new JsonObject(parent, key);
    if (root == null) {
      root = jsonObject;
      parent = root;
    } else {
      parent.addChild(jsonObject);
      parent = jsonObject;
    }
   
    jsonObject.setPosition(startPos, parser.getPosition() - startPos + 1, doc);
   
    char ch;
    do {
      ch = parser.getNextClean();
     
      // Check for empty object.
      if (ch == closeCurly) {
        parser.getNextClean();
        parent = ((JsonElement)parent).getParent();
        break;
      }
     
      if (ch != quote) {
        JsonError jsonError = new JsonError(parent, "JSON key should begin with \"");
        parent.addChild(jsonError);
        throw new JsonTextOutlineParserException();
      }
     
      int start = parser.getPosition();
     
      String attributeKey = doJsonKey();

      ch = parser.getNextClean();
      if (ch != colon) {
        JsonError jsonError = new JsonError(parent, "Expected colon key/value delimitor");
        parent.addChild(jsonError);
        throw new JsonTextOutlineParserException();
      }

      ch = parser.getNextClean();
      if (ch == openCurly) {
        doJsonObject(attributeKey, start);
      } else if (ch == openSquare) {
        doJsonArray(attributeKey, start);
      } else if (ch == n) {
        doJsonNull(attributeKey, start);
      } else if (ch == quote) {
        doJsonValue(attributeKey, start);
      else if (ch == t) {
        doJsonTrueValue(attributeKey, start);
      } else if (ch == f) {
        doJsonFalseValue(attributeKey, start);
      } else if (Character.isDigit(ch) || ch == minus) {
        doJsonNumber(attributeKey, start);
      } else {
        JsonError jsonError = new JsonError(parent, "Expected org.sourceforge.jsonedit.core.core value");
        parent.addChild(jsonError);
        throw new JsonTextOutlineParserException();
      }
     
      ch = parser.getCurrent();
      if (ch == comma) {
        continue;
      }

      if (ch == closeCurly) {
        parser.getNextClean();
        parent = ((JsonElement)parent).getParent();
        break;
      }
     
      JsonError jsonError = new JsonError(parent, "Unexpected object character:" + ch);
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    } while (ch != eof);
  }
 
  /**
   * Parse a Json Array.
   *
   * @param key
   * @param startPos
   * @throws JsonReaderException
   * @throws JsonTextOutlineParserException
   * @throws BadLocationException
   * @throws BadPositionCategoryException
   */
  private void doJsonArray(String key, int startPos) throws JsonReaderException, JsonTextOutlineParserException, BadLocationException, BadPositionCategoryException {
   
    JsonArray jsonArray = new JsonArray(parent, key);
    if (root == null) {
      root = jsonArray;
      parent = root;
    } else {
      parent.addChild(jsonArray);
      parent = jsonArray;
    }
   
    jsonArray.setPosition(startPos, parser.getPosition() - startPos + 1, doc);
   
    char ch;
    do {
      ch = parser.getNextClean();
      int start = parser.getPosition();
      if (ch == openCurly) {
        doJsonObject("", start);
      } else if (ch == openSquare) {
        doJsonArray("", start);
      } else if (ch == n) {
        doJsonNull("", start);
      } else if (ch == quote) {
        doJsonValue("", start);
      } else if (ch == t) {
        doJsonTrueValue("", start);
      } else if (ch == f) {
        doJsonFalseValue("", start);
      } else if (Character.isDigit(ch) || ch == minus) {
        doJsonNumber("", start);
      } else if (ch == closeSquare) {
        parser.getNextClean();
        parent = ((JsonElement)parent).getParent();
        break;
      } else {
        JsonError jsonError = new JsonError(parent, "Expected org.sourceforge.jsonedit.core.core value");
        parent.addChild(jsonError);
        throw new JsonTextOutlineParserException();
      }
     
      ch = parser.getCurrent();
      if (ch == comma) {
        continue;
      }

      if (ch == closeSquare) {
        parser.getNextClean();
        parent = ((JsonElement)parent).getParent();
        break;
      }
     
      JsonError jsonError = new JsonError(parent, "Unexpected array character:" + ch);
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    } while (ch != eof);
  }
 
  /**
   * Parse a Json "true" value.
   *
   * @param key
   * @param start
   * @throws JsonReaderException
   * @throws JsonTextOutlineParserException
   */
  private void doJsonTrueValue(String key, int start) throws JsonReaderException, JsonTextOutlineParserException, BadLocationException, BadPositionCategoryException  {
   
    JsonBoolean jsonBoolean = new JsonBoolean(parent, key);
    parent.addChild(jsonBoolean);
    jsonBoolean.setStart(start, doc);
   
    char ch = parser.getNextChar();
    if (ch != r) {
      JsonError jsonError = new JsonError(parent, "Expect true value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
   
    ch = parser.getNextChar();
    if (ch != u) {
      JsonError jsonError = new JsonError(parent, "Expect true value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
   
    ch = parser.getNextChar();
    if (ch != e) {
      JsonError jsonError = new JsonError(parent, "Expect true value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
   
    jsonBoolean.setLength(parser.getPosition() - start + 1);
   
    ch = parser.getNextClean();
    if (isNotClosed(ch)) {
      JsonError jsonError = new JsonError(parent, "Expected end value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
   
    jsonBoolean.setValue("true");
  }
 
  /**
   * Parse a Json "false" value.
   * @param key
   * @param start
   * @throws JsonReaderException
   * @throws JsonTextOutlineParserException
   */
  private void doJsonFalseValue(String key, int start) throws JsonReaderException, JsonTextOutlineParserException, BadLocationException, BadPositionCategoryException  {
   
    JsonBoolean jsonBoolean = new JsonBoolean(parent, key);
    parent.addChild(jsonBoolean);
    jsonBoolean.setStart(start, doc);
   
    char ch = parser.getNextChar();
    if (ch != a) {
      JsonError jsonError = new JsonError(parent, "Expect true value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
   
    ch = parser.getNextChar();
    if (ch != l) {
      JsonError jsonError = new JsonError(parent, "Expect true value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
   
    ch = parser.getNextChar();
    if (ch != s) {
      JsonError jsonError = new JsonError(parent, "Expect true value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
   
    ch = parser.getNextChar();
    if (ch != e) {
      JsonError jsonError = new JsonError(parent, "Expect true value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
   
    jsonBoolean.setLength(parser.getPosition() - start + 1);
    ch = parser.getNextClean();
    if (isNotClosed(ch)) {
      JsonError jsonError = new JsonError(parent, "Expected end value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
   
    jsonBoolean.setValue("false");
  }
 
  /**
   * Parse a Json null value.
   *
   * @param key
   * @param start
   * @throws JsonReaderException
   * @throws JsonTextOutlineParserException
   */
  private void doJsonNull(String key, int start) throws JsonReaderException, JsonTextOutlineParserException, BadLocationException, BadPositionCategoryException  {
   
    JsonNull jsonNull = new JsonNull(parent, key);
    parent.addChild(jsonNull);
    jsonNull.setStart(start, doc);
   
    char ch = parser.getNextChar();
    if (ch != u) {
      JsonError jsonError = new JsonError(parent, "Expect null value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
   
    ch = parser.getNextChar();
    if (ch != l) {
      JsonError jsonError = new JsonError(parent, "Expect null value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
   
    ch = parser.getNextChar();
    if (ch != l) {
      JsonError jsonError = new JsonError(parent, "Expect null value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
    jsonNull.setLength(parser.getPosition() - start + 1);
   
    ch = parser.getNextClean();
    if (isNotClosed(ch)) {
      JsonError jsonError = new JsonError(parent, "Expected end value");
      parent.addChild(jsonError);
      throw new JsonTextOutlineParserException();
    }
   
    jsonNull.setValue("null");
   
  }
 
  /**
   * Parse a Json string value.
   *
   * @param key
   * @param start
   * @throws JsonReaderException
   * @throws JsonTextOutlineParserException
   */
  private void doJsonValue(String key, int start) throws JsonReaderException, JsonTextOutlineParserException, BadLocationException, BadPositionCategoryException  {
   
    JsonString jsonString = new JsonString(parent, key);
    parent.addChild(jsonString);
    jsonString.setStart(start, doc);
   
    StringBuilder valueBuilder = new StringBuilder();
    char ch;
    do {
      ch = parser.getNextChar();
     
      // TODO check format in values as well.
      if (ch == eof || (ch == quote && parser.getPrevious() != slash)) {
        jsonString.setLength(parser.getPosition() - start + 1);
        ch = parser.getNextClean();
        break;
      }
     
      valueBuilder.append(ch);
    } while (ch != eof);

    jsonString.setValue(valueBuilder.toString());
  }
 
  /**
   * Parse a org.sourceforge.jsonedit.core.core number.
   *
   * @param key
   * @param start
   * @throws JsonReaderException
   * @throws JsonTextOutlineParserException
   */
  private void doJsonNumber(String key, int start) throws JsonReaderException, JsonTextOutlineParserException, BadLocationException, BadPositionCategoryException {
   
    boolean decimalPointSet = false;
   
    JsonNumber jsonNumber = new JsonNumber(parent, key);
    parent.addChild(jsonNumber);
    jsonNumber.setStart(start, doc);
   
    StringBuilder numberBuilder = new StringBuilder();
    numberBuilder.append(parser.getCurrent());
   
    char ch;
    do {
      ch = parser.getNextChar();
     
      if (Character.isDigit(ch)) {
        numberBuilder.append(ch);
        continue;
      }
     
      if (!decimalPointSet && ch == point) {
        decimalPointSet = true;
        numberBuilder.append(ch);
        continue;
      }
     
      jsonNumber.setLength(parser.getPosition() - start);
      if (isClosed(ch)) {
       
        break;
      }
     
      if (isNotWhiteSpace(ch)) {
        JsonError jsonError = new JsonError(parent, "Value " + ch + " not expected here");
        parent.addChild(jsonError);
        throw new JsonTextOutlineParserException();
      }
     
     
      ch = parser.getNextClean();
      if (isNotClosed(ch)) {
        JsonError jsonError = new JsonError(parent, "Expected end value");
        parent.addChild(jsonError);
        throw new JsonTextOutlineParserException();
      }
     
      break;
    } while (ch != eof);
   
    jsonNumber.setValue(numberBuilder.toString());
  }
 
  /**
   * Parse a org.sourceforge.jsonedit.core.core key.
   *
   * @return
   * @throws JsonReaderException
   * @throws JsonTextOutlineParserException
   */
  private String doJsonKey() throws JsonReaderException, JsonTextOutlineParserException {

    StringBuilder keyBuilder = new StringBuilder();
   
    char ch;
    do {
      ch = parser.getNextChar();
     
      if (ch == eof) {
        JsonError jsonError = new JsonError(parent, "Invalid JSON key, no closing \"");
        parent.addChild(jsonError);
        throw new JsonTextOutlineParserException();
      }
     
      if (ch != quote || parser.getPrevious() == slash) {
        keyBuilder.append(ch);
        continue;
      }
     
      break;
    } while (ch != eof);
   
    return keyBuilder.toString();
  }
}

/**
* Exception thrown while parsing.
*
* @author Matt Garner
*
*/
class JsonTextOutlineParserException extends Exception {

  /**
   *
   */
  private static final long serialVersionUID = -75665558665935017L;

  public JsonTextOutlineParserException() {
    super();
  }
 
}
TOP

Related Classes of org.sourceforge.jsonedit.core.outline.JsonTextOutlineParserException

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.