Package dtool.util

Source Code of dtool.util.JsonReaderExt

/*******************************************************************************
* Copyright (c) 2014, 2014 Bruno Medeiros and other Contributors.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Bruno Medeiros - initial API and implementation
*******************************************************************************/
package dtool.util;

import static melnorme.utilbox.core.Assert.AssertNamespace.assertFail;
import static melnorme.utilbox.core.Assert.AssertNamespace.assertUnreachable;

import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;

import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.MalformedJsonException;

/** Utility extensions to JsonReader */
public class JsonReaderExt extends JsonReader {
 
  protected final JsonReaderExt jsonReader = this;
 
  public JsonReaderExt(Reader in) {
    super(in);
  }
 
  public void consumeExpected(JsonToken expectedToken) throws IOException {
    JsonToken tokenType = validateExpectedToken(expectedToken);
    if(tokenType == JsonToken.BEGIN_OBJECT) {
      jsonReader.beginObject();
    } else if(tokenType == JsonToken.END_OBJECT) {
      jsonReader.endObject();
    } else if(tokenType == JsonToken.BEGIN_ARRAY) {
      jsonReader.beginArray();
    } else if(tokenType == JsonToken.END_ARRAY) {
      jsonReader.endArray();
    } else if(tokenType == JsonToken.END_DOCUMENT) {
    } else {
      assertFail();
    }
  }
 
  protected JsonToken validateExpectedToken(JsonToken expectedToken) throws IOException, MalformedJsonException {
    JsonToken tokenType = jsonReader.peek();
    if(tokenType != expectedToken) {
      throw new MalformedJsonException("Expected: " + expectedToken + " Got: " + tokenType);
    }
    return tokenType;
  }
 
  public boolean tryConsume(JsonToken jsonToken) throws IOException {
    if(peek() == jsonToken) {
      consumeExpected(jsonToken);
      return true;
    }
    return false;
  }
 
  public boolean isEOF() throws IOException {
    try {
      if(peek() == JsonToken.END_DOCUMENT) {
        return true;
      }
    } catch (EOFException eof) {
      // This exception is ok. Because of a bug, END_DOCUMENT is sometimes not reported.
      return true;
    }
   
    return false;
  }
 
  /* -----------------  ----------------- */
 
  public void sourceError(String message) throws MalformedJsonException {
    // TODO: add source location to message.
    throw new MalformedJsonException(message);
  }
 
  public void errorUnexpected(JsonToken tokenType) throws MalformedJsonException {
    sourceError("Unexpected token: " + tokenType);
  }
 
  public String consumeStringValue() throws IOException {
    if(jsonReader.peek() != JsonToken.STRING) {
      throw new MalformedJsonException("Expected: " + JsonToken.STRING);
    }
    return jsonReader.nextString();
  }
 
  public ArrayList<String> consumeStringArray(boolean ignoreNulls) throws IOException {
    jsonReader.consumeExpected(JsonToken.BEGIN_ARRAY);
   
    ArrayList<String> strings = new ArrayList<>();
   
    while(jsonReader.hasNext()) {
      JsonToken tokenType = jsonReader.peek();
     
      if(ignoreNulls && tokenType == JsonToken.NULL) {
        jsonReader.nextNull();
        continue;
      }
     
      if(tokenType != JsonToken.STRING) {
        sourceError("Expected String value, instead got: " + tokenType);
      }
     
      String entry = jsonReader.nextString();
      strings.add(entry);
    }
    jsonReader.consumeExpected(JsonToken.END_ARRAY);
    return strings;
  }
 
  public String consumeExpectedPropName() throws IOException {
    JsonToken tokenType = jsonReader.peek();
   
    if(tokenType != JsonToken.NAME) {
      jsonReader.sourceError("Expected property name, instead got: " + tokenType);
    }
   
    // Note: there is a bug in nextName, it throws IllegalStateException insteand of IOE
    // so that's why we check peek ourselves.
    return jsonReader.nextName();
  }
 
  public String consumeExpectedName() throws IOException {
    return consumeExpectedPropName();
  }
 
  /* -----------------  ----------------- */
 
  public Object readJsonValue() throws IOException {
    return readJsonValue(this);
  }
 
  public static Object readJsonValue(JsonReaderExt jsonParser) throws IOException {
    switch (jsonParser.peek()) {
    case NULL:
      jsonParser.nextNull(); return null;
    case BOOLEAN:
      return jsonParser.nextBoolean();
    case NUMBER:
      long longValue = jsonParser.nextLong();
      int intValue = (int) longValue;
      if(intValue == longValue) {
        return intValue; // return integer if value can be stored in int
      } else {
        return longValue;
      }
    case STRING:
      return jsonParser.nextString();
    case BEGIN_ARRAY:
      return jsonParser.readJsonArray();
    case BEGIN_OBJECT:
      return jsonParser.readJsonObject();
    case END_ARRAY:
    case END_OBJECT:
    case END_DOCUMENT:
    case NAME:
      jsonParser.sourceError("Invalid JSON token");
      return null;
    }
   
    throw assertUnreachable();
  }
 
  public HashMap<String, Object> readJsonObject() throws IOException {
    return readJsonObject(this);
  }
 
  public static HashMap<String, Object> readJsonObject(JsonReaderExt jsonParser) throws IOException {
    jsonParser.consumeExpected(JsonToken.BEGIN_OBJECT);
   
    HashMap<String, Object> jsonObject = new HashMap<>();
   
    while(jsonParser.tryConsume(JsonToken.END_OBJECT) == false) {
      String propName = jsonParser.consumeExpectedPropName();
      Object propvalue = readJsonValue(jsonParser);
      jsonObject.put(propName, propvalue);
    }
   
    return jsonObject;
  }
 
  public ArrayList<Object> readJsonArray() throws IOException {
    jsonReader.consumeExpected(JsonToken.BEGIN_ARRAY);
   
    ArrayList<Object> array = new ArrayList<>();
    while(jsonReader.hasNext()) {
      array.add(readJsonValue());
    }
    jsonReader.consumeExpected(JsonToken.END_ARRAY);
    return array;
  }
 
}
TOP

Related Classes of dtool.util.JsonReaderExt

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.