GithubHelp home page GithubHelp logo

pierreconstantial / maja Goto Github PK

View Code? Open in Web Editor NEW

This project forked from io-0/maja

0.0 0.0 0.0 316 KB

Maps Java Objects to JSON (or YAML or Maps) and back

License: Apache License 2.0

Java 100.00%

maja's Introduction

Maja

About

Maps Java Objects to JSON (or YAML or Maps) and back without information loss. Provides validators to tighten mapping.

Combining those features enables one to implement e.g. OpenAPI Specification.

Information loss?

A property in JSON can have a value (null or otherwise) or be absent/undefined. A property in Java can't be absent/undefined at runtime. There are multiple ways to deal with that in Java. Since Java 8 one could e.g. utilize Optional for properties where this difference matters. Maja's approach is to store in a Set if a property was set.

Furthermore, JSON naming conventions are not as strict as in Java. Maja's approach to deal with this are @WithUnconventionalName Annotations.

Usage

Import

Use Maven or Gradle, e.g. add repository and dependency to build.gradle:

repositories {
  ...
  maven { url "https://jitpack.io" }
  ...
}
dependencies {
  ...
  implementation "com.github.io-0:maja:develop-SNAPSHOT"
  ...
}

Define Mapping via Java Classes

We can work with POJOs if the difference between null and absent should be ignored. Otherwise PropertyBundle should be implemented and it's marker method should be used in Setters. The following example uses fluent Setters and Lombok Annotations (constants for property names are useful for Validators):

@NoArgsConstructor
@Getter
@ToString
public class Person extends PropertyBundle {
  public static final String FIRST_NAME = "firstName";
  public static final String LAST_NAME = "lastName";

  @WithUnconventionalName("first name")
  private String firstName;
  private String lastName;

  public Person setFirstName(String value) {
    this.firstName = value;
    markPropertySet(FIRST_NAME);
    return this;
  }

  public Person setLastName(String value) {
    this.lastName = value;
    markPropertySet(LAST_NAME);
    return this;
  }
}

This example also demonstrates the use of @WithUnconventionalName Annotations.

If a property type is an Interface Maja tries to instantiate it if a default method, static method or context instantiator exists that returns the interface type and takes Map<String, Object> as parameter. The following example assumes that ImplementationA implements InterfaceA:

public interface InterfaceA {
  default InterfaceA getInstance(Map<String, Object> jsonAsMap) {
    return Mapper.fromMap(jsonAsMap, ImplementationA.class);
  }
}

Validation

To further tighten the mapping validators can be defined:

public interface PersonValidator {
  Validator<Person> instance = Validator.of(
    PropertyConstraint.on(FIRST_NAME, required, notNull, minLength(2)),
    PropertyConstraint.on(LAST_NAME, notNull)
  );
}

For a list of all available validators, see Built In Property Validators. For further information check the Tests.

Bringing it all together

Mapping can be done from POJO or PropertyBundle to JSON String or a Map and back. An issue collector needs to be supplied. The collected issues can then be fed into validation, which will throw an Exception on problems (containing them all). Example:

String json = "{ \"first name\": \"Maja\" }";
PropertyIssues mappingIssues = PropertyIssues.of();

Person person = Mapper.fromJson(json, mappingIssues::add, Person.class);

Person validPerson = Validator.of(mappingIssues).and(PersonValidator.instance).ensureValidity(person);

Property<String> firstName = validPerson.getProperty(Person.FIRST_NAME);
Property<String> lastName = validPerson.getProperty(Person.LAST_NAME);

firstName.ifAssigned(valueOrNull -> System.out.println(valueOrNull)); // prints 'Maja'
lastName.ifUnassigned(() -> System.out.println("lastName was absent")); // prints 'lastName was absent'

For further information check the Tests.

Built In Property Validators

Most validators will only act if a non null value is present. If this is not desired combine the validator with the required validator or the notNull validator or both.

All Types

  • notNull
  • required
  • valid (for validator stacking)
  • lazy (for validator stacking)

String Types

  • pattern
  • passwordFormat
  • binaryFormat
  • byteFormat
  • emailFormat
  • hostnameFormat
  • ipV4Format
  • ipV6Format
  • maxLength
  • minLength

Integer, Long, Float, Double, BigDecimal Types

  • exclusiveMaximum
  • exclusiveMinimum
  • maximum
  • minimum
  • multipleOf

Collection and Map Types

  • maxItems
  • minItems
  • each (for validator stacking)

Property Issue Error Codes

From Mapping

  • Weird String Value
  • Instantiation Problem
  • Weird Key
  • Weird Number Value
  • Unexpected Token
  • Missing Instantiator

From Validation

  • Not Null Violation
  • Required Violation
  • Pattern Violation, %value%
  • Password Format Violation
  • Binary Format Violation
  • Byte Format Violation
  • Email Format Violation
  • Hostname Format Violation
  • IP V4 Format Violation
  • IP V6 Format Violation
  • Max Length Violation, %value%
  • Min Length Violation, %value%
  • Exclusive Maximum Violation, %value%
  • Exclusive Minimum Violation, %value%
  • Maximum Violation, %value%
  • Minimum Violation, %value%
  • Multiple Of Violation, %value%
  • Max Items Violation, %value%
  • Min Items Violation, %value%

maja's People

Contributors

vid14114 avatar io-0 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.