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

com.github.dakusui.scriptiveunit.loaders.json.JsonBasedLoader Maven / Gradle / Ivy

package com.github.dakusui.scriptiveunit.loaders.json;

import com.github.dakusui.scriptiveunit.Session;
import com.github.dakusui.scriptiveunit.core.Config;
import com.github.dakusui.scriptiveunit.core.JsonUtils;
import com.github.dakusui.scriptiveunit.core.Preprocessor;
import com.github.dakusui.scriptiveunit.loaders.json.JsonBeans.TestSuiteDescriptorBean;
import com.github.dakusui.scriptiveunit.model.TestSuiteDescriptor;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.JsonNodeFactory;
import org.codehaus.jackson.node.ObjectNode;
import org.codehaus.jackson.node.TextNode;

import java.io.IOException;
import java.util.AbstractList;
import java.util.Collections;
import java.util.List;

import static com.github.dakusui.scriptiveunit.core.JsonUtils.array;
import static com.github.dakusui.scriptiveunit.core.JsonUtils.object;
import static com.github.dakusui.scriptiveunit.core.JsonUtils.pathMatcher;
import static com.github.dakusui.scriptiveunit.core.Utils.*;
import static com.github.dakusui.scriptiveunit.exceptions.ScriptiveUnitException.wrap;
import static com.github.dakusui.scriptiveunit.exceptions.SyntaxException.*;

public class JsonBasedLoader extends TestSuiteDescriptor.Loader.Base {

  private static final String EXTENDS_KEYWORD = "$extends";
  /**
   * A resource that holds default values of ScriptiveUnit.
   */
  private static final String DEFAULTS_JSON   = "defaults/values.json";

  @SuppressWarnings("unused")
  public JsonBasedLoader(Config config) {
    super(config);
  }

  @Override
  public TestSuiteDescriptor loadTestSuiteDescriptor(Session session) {
    try {
      return new ObjectMapper()
          .readValue(
              readScript(session
                  .getConfig()
                  .getScriptResourceName()
              ),
              TestSuiteDescriptorBean.class
          ).create(session);
    } catch (IOException e) {
      throw wrap(e);
    }
  }

  protected ObjectNode readObjectNodeWithMerging(String resourceName) {
    ObjectNode child = checkObjectNode(preprocess(readJsonNodeFromStream(openResourceAsStream(resourceName))));
    ObjectNode work = JsonNodeFactory.instance.objectNode();
    if (child.has(EXTENDS_KEYWORD)) {
      getParentsOf(child).forEach(s -> deepMerge(checkObjectNode(readObjectNodeWithMerging(s)), work));
    }
    return deepMerge(child, work);
  }

  private JsonNode preprocess(JsonNode inputNode) {
    JsonNode ret = inputNode;
    for (Preprocessor each : getPreprocessors()) {
      ret = Preprocessor.translate(each, ret);
    }
    return ret;
  }

  protected List getPreprocessors() {
    return Collections.singletonList(
        JsonUtils.preprocessor(
            (JsonNode targetElement) ->
                targetElement instanceof ObjectNode ?
                    targetElement :
                    object()
                        .$(
                            "type",
                            "simple")
                        .$(
                            "args",
                            targetElement instanceof ArrayNode ?
                                targetElement :
                                array().$(targetElement).build())
                        .build(),
            pathMatcher("factorSpace", "factors", ".*")
        )

    );
  }

  private ObjectNode readScript(String scriptResourceName) {
    ObjectNode work = readObjectNodeWithMerging(scriptResourceName);
    ObjectNode ret = checkObjectNode(readJsonNodeFromStream(openResourceAsStream(DEFAULTS_JSON)));
    ret = deepMerge(work, ret);
    ret.remove(EXTENDS_KEYWORD);
    return ret;
  }

  private AbstractList getParentsOf(final ObjectNode child) {
    return new AbstractList() {
      ArrayNode parents = checkArrayNode(child.get(EXTENDS_KEYWORD));

      @Override
      public int size() {
        return parents.size();
      }

      @Override
      public String get(int index) {
        return checkTextNode(parents.get(index)).asText();
      }
    };
  }

  private TextNode checkTextNode(JsonNode curr) {
    return (TextNode) check(curr, v -> curr.isTextual(), () -> nonText(curr));
  }

  private ObjectNode checkObjectNode(JsonNode curr) {
    return (ObjectNode) check(curr, v -> curr.isObject(), () -> nonObject(curr));
  }

  private ArrayNode checkArrayNode(JsonNode curr) {
    return (ArrayNode) check(curr, v -> curr.isArray(), () -> nonArray(curr));
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy