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

org.qas.api.transform.JsonUnmarshallerContext Maven / Gradle / Ivy

The newest version!
package org.qas.api.transform;

import static com.fasterxml.jackson.core.JsonToken.START_OBJECT;
import static com.fasterxml.jackson.core.JsonToken.END_OBJECT;
import static com.fasterxml.jackson.core.JsonToken.START_ARRAY;
import static com.fasterxml.jackson.core.JsonToken.END_ARRAY;
import static com.fasterxml.jackson.core.JsonToken.FIELD_NAME;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import org.qas.api.http.HttpResponse;

import java.io.IOException;
import java.util.*;

/**
 * JsonUnmarshallerContext
 *
 * @author Dzung Nguyen
 * @version $Id JsonUnmarshallerContext 2014-03-27 11:10:30z dungvnguyen $
 * @since 1.0
 */
public class JsonUnmarshallerContext {
  //~ class properties ========================================================
  private final JsonParser jsonParser;
  private final HttpResponse httpResponse;

  private final Stack stack = new Stack();
  private String stackString = "";
  private String currentField;

  private String lastParsedParentElement;
  private Map metadata = new HashMap();
  private List metadataExpressions = new ArrayList();

  public JsonToken currentToken;
  private JsonToken nextToken;

  //~ class members ===========================================================
  public JsonUnmarshallerContext(JsonParser jsonParser) {
    this(jsonParser, null);
  }

  public JsonUnmarshallerContext(JsonParser jsonParser, HttpResponse httpResponse) {
    this.jsonParser = jsonParser;
    this.httpResponse = httpResponse;
  }

  public String getHeader(String header) {
    if (httpResponse == null) return null;
    return ((Map) httpResponse.getHeaders()).get(header);
  }

  public HttpResponse getHttpResponse() {
    return httpResponse;
  }

  public int getCurrentDepth() {
    int depth = 0;
    for (String s : stack) {
      if (!(s.equals(START_OBJECT.asString()) || s.equals(START_ARRAY.asString()))) {
        depth++;
      }
    }
    if (currentField != null) depth++;
    return depth;
  }

  public String readText() throws IOException {
    switch (currentToken) {
      case VALUE_STRING:
        return jsonParser.getText();
      case VALUE_FALSE: return "false";
      case VALUE_TRUE: return "true";
      case VALUE_NULL: return null;
      case VALUE_NUMBER_FLOAT:
      case VALUE_NUMBER_INT:
        return jsonParser.getNumberValue().toString();
      case FIELD_NAME:
        return jsonParser.getText();
      default:
        throw new RuntimeException("We expected a VALUE token but got: " + currentToken);
    }
  }

  public boolean isStartOfDocument() {
    return jsonParser == null || jsonParser.getCurrentToken() == null;
  }

  public String getCurrentParentElement() {
    String[] tokens = stackString.split("/");
    if (tokens.length == 0) return "";
    return tokens[tokens.length - 1];
  }

  public boolean testExpression(String expression) {
    if (expression.equals(".")) return true;
    return stackString.endsWith(expression.startsWith("/") ? expression : "/".concat(expression));
  }

  public boolean testExpression(String expression, int stackDepth) {
    if (expression.equals(".")) return true;
    int index = -1;
    while ((index = expression.indexOf("/", index+1)) > -1) {
      if (expression.charAt(index + 1) != '@') {
        stackDepth++;
      }
    }
    return stackString.endsWith(expression.startsWith("/") ? expression : "/".concat(expression))
        && stackDepth == getCurrentDepth();
  }

  public JsonToken nextToken() throws IOException {
    JsonToken token = (nextToken != null) ? nextToken : jsonParser.nextToken();
    this.currentToken = token;
    nextToken = null;
    updateContext();

    return token;
  }

  public JsonToken peek() throws IOException {
    if (nextToken != null) return nextToken;
    nextToken = jsonParser.nextToken();
    return nextToken;
  }

  public JsonParser getJsonParser() {
    return jsonParser;
  }

  public Map getMetadata() {
    return metadata;
  }

  public void registerMetadataExpression(String expression, int targetDepth, String storageKey) {
    metadataExpressions.add(new MetadataExpression(expression, targetDepth, storageKey));
  }

  private void updateContext() throws IOException {
    lastParsedParentElement = null;
    if (currentToken == null) return;

    if (currentToken == START_ARRAY || currentToken == START_OBJECT) {
      if (currentField != null) {
        stack.push(currentField);
        stack.push(currentToken.asString());
        currentField = null;
      }
    } else if (currentToken == END_ARRAY || currentToken == END_OBJECT) {
      if (!stack.isEmpty()) {
        boolean squareBracketsMatch = currentToken == END_ARRAY && stack.peek().equals(START_ARRAY.asString());
        boolean curlyBracketMatch = currentToken == END_OBJECT && stack.peek().equals(START_OBJECT.asString());

        if (squareBracketsMatch || curlyBracketMatch) {
          stack.pop();
          lastParsedParentElement = stack.pop();
        }
      }
      currentField = null;
    } else if (currentToken == FIELD_NAME)  {
      currentField = jsonParser.getText();
    }

    rebuildStackString();
  }

  public String getLastParsedParentElement() {
    return lastParsedParentElement;
  }

  private void rebuildStackString() {
    stackString = "";
    for (String s : stack) {
      if (! (s.equals(START_ARRAY.asString()) || s.equals(START_OBJECT.asString()))) {
        stackString += "/" + s;
      }
    }

    if (currentField != null) {
      stackString += "/" + currentField;
    }

    if ("".equals(stackString)) stackString = "/";
  }

  @Override
  public String toString() {
    return stackString;
  }
  //~ class helpers ===========================================================
  /**
   * MetadataExpression.
   *
   * @author: Dzung Nguyen
   * @version: $Id JsonUnmarshallerContext 2013-08-26 04:18:30z nguyen_dv $
   * @since 1.0
   */
  private class MetadataExpression {
    public String expression;
    public int targetDepth;
    public String key;

    public MetadataExpression(String expression, int targetDepth, String key) {
      this.expression = expression;
      this.targetDepth = targetDepth;
      this.key = key;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy