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

org.jsonx.Validator Maven / Gradle / Ivy

Go to download

The JSD Binding Validator validates JSON documents against JSD or JSDx schemas.

The newest version!
/* Copyright (c) 2018 JSONx
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * You should have received a copy of The MIT License (MIT) along with this
 * program. If not, see .
 */

package org.jsonx;

import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.libj.jci.CompilationException;
import org.libj.jci.InMemoryCompiler;
import org.libj.lang.Numbers;
import org.libj.lang.PackageLoader;
import org.libj.lang.PackageNotFoundException;
import org.libj.net.URLs;
import org.openjax.json.JsonReader;

/**
 * Utility for validating JSON documents to a JSD or JSDx schema.
 */
public class Validator {
  private static void trapPrintUsage() {
    System.err.println("Usage: Validator  ...");
    System.exit(1);
  }

  private static void validate(final JsonReader reader, final Set> objectClasses, final Set> arrayClasses, final ArrayList errors) throws IOException {
    final long i = reader.readToken();
    final int off = Numbers.Composite.decodeInt(i, 0);
    final char token = reader.bufToChar(off);
    try {
      if (token == '{') {
        if (objectClasses.size() > 0)
          JxDecoder.VALIDATING.parseObject(reader, objectClasses);
        else
          errors.add("No object definition present in schema");
      }
      else if (token == '[') {
        if (arrayClasses.size() > 0)
          JxDecoder.VALIDATING.parseArray(reader, arrayClasses);
        else
          errors.add("No array definition present in schema");
      }
      else {
        throw new IllegalArgumentException("Unable to parse JSON document");
      }
    }
    catch (final DecodeException e) {
      errors.add(e.getMessage());
    }
  }

  public static void main(final String[] args) throws CompilationException, IOException, PackageNotFoundException {
    if (args.length < 2)
      trapPrintUsage();

    if (validate(args) == 1)
      System.exit(1);
  }

  @SuppressWarnings("unchecked")
  static int validate(final String[] args) throws CompilationException, IOException, PackageNotFoundException {
    final String pkg = "jsonx";
    final SchemaElement[] schemas = Generator.parse(new Settings.Builder().withNamespacePackage(t -> pkg + "._" + Integer.toHexString(t.hashCode())).build(), URLs.fromStringPath(args[0]));
    final InMemoryCompiler compiler = new InMemoryCompiler();
    for (final SchemaElement schema : schemas) { // [A]
      final Map source = schema.toSource();
      for (final Map.Entry entry : source.entrySet()) // [S]
        compiler.addSource(entry.getValue());
    }

    final ClassLoader classLoader = compiler.compile();

    final HashSet> objectClasses = new HashSet<>();
    final HashSet> arrayClasses = new HashSet<>();
    PackageLoader.getPackageLoader(classLoader).loadPackage(pkg, cls -> {
      if (cls.getDeclaringClass() == null) {
        if (Annotation.class.isAssignableFrom(cls))
          arrayClasses.add((Class)cls);
        else if (!Modifier.isAbstract(cls.getModifiers()) && JxObject.class.isAssignableFrom(cls))
          objectClasses.add((Class)cls);
      }

      return true;
    });

    final ArrayList errors = new ArrayList<>();
    for (int i = 1, i$ = args.length; i < i$; ++i) {// [A]
      try (final JsonReader reader = new JsonReader(new InputStreamReader(URLs.fromStringPath(args[i]).openStream()))) {
        validate(reader, objectClasses, arrayClasses, errors);
      }
    }

    final int size = errors.size();
    for (int i = 0; i < size; ++i) // [RA]
      System.err.println(errors.get(i));

    return size == 0 ? 0 : 1;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy