Thursday 11 December 2014

Groovy JSON Validator

Aim of this blog is to validate a JSON document using XML based IScreen validation API by converting a JSON document into a Groovy map.

So, we have an Invoice in JSON format:

 {  
  "id": 1,  
  "invoiceNumber": 100,  
  "orderDetail": {  
   "companyName": "ABC Corp",  
   "products": {  
    "product": [   
     {  
      "name":"Benetton T-Shirt",  
      "description": {  
       "order": {  
        "quantity": "1000000000",  
        "amountPerPiece": "100"  
       }  
      }  
     }  
     ]  
   }  
  }  
 }  


We will be using Groovy JsonSlurper class parseText method to convert JSON document into a Groovy Map.

We will be using IScreen validation framework to validate the Map against a validation XML file:

 <?xml version="1.0" encoding="UTF-8"?>  
 <validation-root namespace="com.blogspot.javasampleprogram.validators"  
      default-resource="messages">  
      <include file="org/iscreen/validators.xml" />  
      <!-- This will validate the entire object graph, with the order being the   
           root object. -->  
      <validation-set id="invoice">  
           <!-- NumberRange Validator -->  
           <use-validator ref="org.iscreen.NumberRangeValidator"  
                name="id">  
                <mapping from="id" to="value" />  
                <label>Invoice Id</label>  
                <constraint property="minimumValue">10</constraint>  
                <constraint property="maximumValue">100</constraint>  
           </use-validator>  
           <!-- Custom messages -->  
           <use-validator ref="org.iscreen.NumberRangeValidator"  
                name="invoiceNumber">  
                <mapping from="invoiceNumber" to="value" />  
                <label>Invoice Number</label>  
                <constraint property="minimumValue">1000</constraint>  
                <constraint property="maximumValue">99999999</constraint>  
                <failure property="rangeFailure">  
                     ${label} can be between ${validator.minimumValue} and ${validator.maximumValue} and is mandatory  
                </failure>  
           </use-validator>  
           <use-validation-set ref="orderDetail" map="orderDetail" />  
      </validation-set>  
      <!-- Validates a OrderDetail. -->  
      <validation-set id="orderDetail">  
           <!-- String Validator -->  
           <use-validator ref="org.iscreen.StringValidator" name="companyName">  
                <mapping from="companyName" to="value" />  
                <label>Company Name</label>  
                <constraint property="minLength">10</constraint>  
                <constraint property="maxLength">65</constraint>  
           </use-validator>  
           <!-- Null Validator -->  
           <use-validator name="NullValidator" ref="org.iscreen.NullValidator">  
                <mapping from="invoiceAddress" to="value" />  
                <label>Invoice Address</label>  
                <failure property="defaultFailure">  
                     ${label} is a mandatory field.  
                </failure>  
           </use-validator>  
           <use-validation-set ref="products" map="products"/>  
      </validation-set>  
      <!-- Validates a Products -->  
      <validation-set id="products">  
           <!-- List validator -->  
           <use-validation-set ref="product" map="product" iterate="true" />  
      </validation-set>  
      <!-- Validates a Product -->  
      <validation-set id="product">  
           <use-validation-set ref="description" map="description" />  
      </validation-set>  
      <!-- Validates a Description -->  
      <validation-set id="description">  
           <use-validation-set ref="order" map="order" />  
      </validation-set>  
      <!-- Validates a Order -->  
      <validation-set id="order">  
           <!-- Custom messages -->  
           <use-validator ref="org.iscreen.NumberRangeValidator"  
                name="quantity">  
                <mapping from="quantity" to="value" />  
                <label>Quantity</label>  
                <constraint property="minimumValue">1</constraint>  
                <constraint property="maximumValue">999999999</constraint>  
                <failure property="rangeFailure">  
                     ${label} can be between ${validator.minimumValue} and ${validator.maximumValue} and is mandatory  
                </failure>  
           </use-validator>  
      </validation-set>  
 </validation-root>  

Before we proceed let me explain the validation xml above:

For each class we will be creating a validation-set inside which we can either use IScreen built-in validators or we can also use custom validators to validate the fields (For more info on how to create custom validator please see).

Here we are validating the 'Id' using built-in 'NumberRangeValidator' to make sure 'Id' field has a minimum value of 10 and  maximum value of 100.

Similarly, we are validating 'CompanyName' field inside the OrderDetail to validate its max and min length. Same goes for 'InvoiceAddress' field which is checked for Not Null validation.


 package com.blogspot.javasampleprogram  
 import java.util.List  
 import java.util.Locale  
 import org.iscreen.DocumentationIterator  
 import org.iscreen.ValidationException  
 import org.iscreen.ValidationFactory  
 import org.iscreen.ValidationFactoryConfig  
 import org.iscreen.ValidationFailure  
 import org.iscreen.ValidationServiceWrapper  
 import groovy.json.JsonSlurper  

 class JSONValidator {  

   private static final String VALIDATION_CONFIG = "com/blogspot/javasampleprogram/my_validations.xml"  

   static main(args) {  
     // Step 1: Load json  
     File f = new File("/home/devbox/workspace/JSONGroovyValidator/src/com/blogspot/javasampleprogram/test.json")  
     FileReader fr = new FileReader(f)  
     StringBuffer sbuf = new StringBuffer(500)  
     String s = null  
     while((s = fr.readLine())!= null) {  
       sbuf.append(s)  
     }  
     println sbuf.toString()  
    
    // Step 2: generate Invoice Map  
     def invoice = new JsonSlurper().parseText(escapeJson(sbuf.toString()))  
     ValidationFactoryConfig factory  
     ValidationServiceWrapper service  
     DocumentationIterator it  
     
     //Step 3: Load validation configurations  
     factory = new ValidationFactoryConfig(ValidationFactory.FACTORY_OGNL_XML,  
         VALIDATION_CONFIG,  
         Locale.getDefault(),  
         null)  
     service = new ValidationServiceWrapper(factory, "com.blogspot.javasampleprogram.validators.invoice")  
     try {  
      
       // Step 4: validate Invoice Map  
       service.validate(invoice)  
       System.out.println("Validation successful!")  
     } catch (ValidationException e) {  
       List failures  
       failures = e.getFailures(ValidationFailure.FAILURE)  
       System.out.println("Validation Failures found!\n")  
       for (int i = 0; i < failures.size(); i++) {  
         System.out.println(((ValidationFailure) failures.get(i)).getMessage())  
       }  
     }  
   }  
   static final String escapeJson(final String json) {  
     return json.replaceAll('&', '&amp;').replaceAll('>', '&gt;').replaceAll('>', '&lt;')  
   }  
 }  
Above code is validating the json in 4 steps:

  1. Load json data
  2. Generate Groovy Map from json string
  3. Load validation IScreen configurations
  4. Validate Map against Iscreen configuration
so if you run the code above you will get the following output:

 Validation Failures found!  

 Invoice Id must be at least 10 and no greater than 100.  
 Invoice Number can be between 1000 and 99999999 and is mandatory  
 Company Name must be at least 10 characters long.  
 Invoice Address is a mandatory field.  
 Quantity can be between 1 and 999999999 and is mandatory  


Please add the following jars to your project:

  1. javassist-3.7.ga.jar
  2. iScreen-ognl-2-0-1.jar
  3. ognl-3.0.jar
Add Groovy Capabilities to your eclipse project (Make sure you have groovy eclipse plugin installed):


Now you should see Groovy libs in your project:





Project Structure:








Wednesday 10 December 2014

JSON Validation in Java

Aim of this blog is to validate a JSON document using XML based IScreen validation API.

So, we have an Invoice in JSON format:

 {  
  "id": 1,  
  "invoiceNumber": 100,  
  "orderDetail": {  
   "companyName": "ABC Corp",  
   "products": {  
    "product": [   
     {  
      "name":"Benetton T-Shirt",  
      "description": {  
       "order": {  
        "quantity": "1000000000",  
        "amountPerPiece": "100"  
       }  
      }  
     }  
     ]  
   }  
  }  
 }  


We will be using Jackson Java API to convert JSON document into Invoice object.
Following is the Invoice class that I have created:

 package com.blogspot.javasampleprogram;  
 import java.io.Serializable;  
 import java.util.List;  

 public class Invoice implements Serializable {  
   private String id;  
   private String invoiceNumber;  
   private OrderDetail orderDetail;  
   public String getId() {  
     return id;  
   }  
   public void setId(String id) {  
     this.id = id;  
   }  
   public String getInvoiceNumber() {  
     return invoiceNumber;  
   }  
   public void setInvoiceNumber(String invoiceNumber) {  
     this.invoiceNumber = invoiceNumber;  
   }  
   public OrderDetail getOrderDetail() {  
     return orderDetail;  
   }  
   public void setOrderDetail(OrderDetail orderDetail) {  
     this.orderDetail = orderDetail;  
   }  
 }  

 class OrderDetail implements Serializable {  
   private String companyName;  
   private String invoiceAddress;  
   private Products products;  
   public String getCompanyName() {  
     return companyName;  
   }  
   public void setCompanyName(String companyName) {  
     this.companyName = companyName;  
   }  
   public Products getProducts() {  
     return products;  
   }  
   public void setProducts(Products products) {  
     this.products = products;  
   }  
   public String getInvoiceAddress() {  
     return invoiceAddress;  
   }  
   public void setInvoiceAddress(String invoiceAddress) {  
     this.invoiceAddress = invoiceAddress;  
   }  
 }  

 class Products implements Serializable {  
   private Product[] product;  
   public Product[] getProduct() {  
     return product;  
   }  
   public void setProduct(Product[] product) {  
     this.product = product;  
   }  
 }  

 class Product implements Serializable {  
   private String name;  
   private Description description;  
   public String getName() {  
     return name;  
   }  
   public void setName(String name) {  
     this.name = name;  
   }  
   public Description getDescription() {  
     return description;  
   }  
   public void setDescription(Description description) {  
     this.description = description;  
   }  
 }  

 class Description implements Serializable {  
   private Order order;  
   public Order getOrder() {  
     return order;  
   }  
   public void setOrder(Order order) {  
     this.order = order;  
   }  
 }  

 class Order {  
   private String quantity;  
   private String AmountPerPiece;  
   public String getQuantity() {  
     return quantity;  
   }  
   public void setQuantity(String quantity) {  
     this.quantity = quantity;  
   }  
   public String getAmountPerPiece() {  
     return AmountPerPiece;  
   }  
   public void setAmountPerPiece(String amountPerPiece) {  
     AmountPerPiece = amountPerPiece;  
   }  
 }  


We will be using IScreen validation framework to validate the Invoice object against a validation XML file:

 <?xml version="1.0" encoding="UTF-8"?>  
 <validation-root namespace="com.blogspot.javasampleprogram.validators"  
      default-resource="messages">  
      <include file="org/iscreen/validators.xml" />  
      <!-- This will validate the entire object graph, with the order being the   
           root object. -->  
      <validation-set id="invoice">  
           <!-- NumberRange Validator -->  
           <use-validator ref="org.iscreen.NumberRangeValidator"  
                name="Id">  
                <mapping from="Id" to="value" />  
                <label>Invoice Id</label>  
                <constraint property="minimumValue">10</constraint>  
                <constraint property="maximumValue">100</constraint>  
           </use-validator>  
           <!-- Custom messages -->  
           <use-validator ref="org.iscreen.NumberRangeValidator"  
                name="InvoiceNumber">  
                <mapping from="InvoiceNumber" to="value" />  
                <label>Invoice Number</label>  
                <constraint property="minimumValue">1000</constraint>  
                <constraint property="maximumValue">99999999</constraint>  
                <failure property="rangeFailure">  
                     ${label} can be between ${validator.minimumValue} and ${validator.maximumValue} and is mandatory  
                </failure>  
           </use-validator>  
           <use-validation-set ref="OrderDetail" map="OrderDetail" />  
      </validation-set>  
      <!-- Validates a OrderDetail. -->  
      <validation-set id="OrderDetail">  
           <!-- String Validator -->  
           <use-validator ref="org.iscreen.StringValidator" name="CompanyName">  
                <mapping from="CompanyName" to="value" />  
                <label>Company Name</label>  
                <constraint property="minLength">10</constraint>  
                <constraint property="maxLength">65</constraint>  
           </use-validator>  
           <!-- Null Validator -->  
           <use-validator name="NullValidator" ref="org.iscreen.NullValidator">  
                <mapping from="InvoiceAddress" to="value" />  
                <label>Invoice Address</label>  
                <failure property="defaultFailure">  
                     ${label} is a mandatory field.  
                </failure>  
           </use-validator>  
           <use-validation-set ref="Products" map="Products"/>  
      </validation-set>  
      <!-- Validates a Products-->  
      <validation-set id="Products">  
           <!-- List validator -->  
           <use-validation-set ref="Product" map="Product" iterate="true" />  
      </validation-set>  
      <!-- Validates a Product-->  
      <validation-set id="Product">  
           <use-validation-set ref="Description" map="Description" />  
      </validation-set>  
      <!-- Validates a Description-->  
      <validation-set id="Description">  
           <use-validation-set ref="Order" map="Order" />  
      </validation-set>  
      <!-- Validates a Order -->  
      <validation-set id="Order">  
           <!-- Custom messages -->  
           <use-validator ref="org.iscreen.NumberRangeValidator"  
                name="Quantity">  
                <mapping from="Quantity" to="value" />  
                <label>Quantity</label>  
                <constraint property="minimumValue">1</constraint>  
                <constraint property="maximumValue">999999999</constraint>  
                <failure property="rangeFailure">  
                     ${label} can be between ${validator.minimumValue} and ${validator.maximumValue} and is mandatory  
                </failure>  
           </use-validator>  
      </validation-set>  
 </validation-root>  

Before we proceed let me explain the validation xml above:

For each class we will be creating a validation-set inside which we can either use IScreen built-in validators or we can also use custom validators to validate the fields (For more info on how to create custom validator please see).

Here we are validating the 'Id' inside the Invoice object using built-in 'NumberRangeValidator' to make sure 'Id' field has a minimum value of 10 and  maximum value of 100.

Similarly, we are validating 'CompanyName' field inside the OrderDetail object to make validate its max and min length. Same goes for 'InvoiceAddress' field which is checked for Not Null validation.


 package com.blogspot.javasampleprogram;  
 import java.io.File;  
 import java.io.IOException;  
 import java.util.List;  
 import java.util.Locale;  
 import org.codehaus.jackson.map.ObjectMapper;  
 import org.iscreen.DocumentationIterator;  
 import org.iscreen.ValidationException;  
 import org.iscreen.ValidationFactory;  
 import org.iscreen.ValidationFactoryConfig;  
 import org.iscreen.ValidationFailure;  
 import org.iscreen.ValidationServiceWrapper;  
 public class JSONValidator {  
   private static final String VALIDATION_CONFIG = "com/blogspot/javasampleprogram/my_validations.xml";  
   public static void main(String[] args) throws IOException {  
     // Step 1: Load json & generate Invoice Object  
     Invoice invoice = createJsonObject();  
     ValidationFactoryConfig factory;  
     ValidationServiceWrapper service;  
     DocumentationIterator it;  
     // Step 2: Load validation configurations  
     factory = new ValidationFactoryConfig(ValidationFactory.FACTORY_OGNL_XML,  
         VALIDATION_CONFIG,  
         Locale.getDefault(),  
         null);  
     service = new ValidationServiceWrapper(factory, "com.blogspot.javasampleprogram.validators.invoice");  
     try {  
       // Step 3: validate Invoice Object  
       service.validate(invoice);  
       System.out.println("Validation successful!");  
     } catch (ValidationException e) {  
       List failures = e.getFailures(ValidationFailure.FAILURE);  
       System.out.println("Validation Failures found!\n");  
       for (int i = 0; i < failures.size(); i++) {  
         System.out.println(((ValidationFailure) failures.get(i)).getMessage());  
       }  
     }  
   }  
   static final String escapeJson(final String json) {  
     return json.replaceAll("&", "&amp;").replaceAll(">", "&gt;").replaceAll(">", "&lt;");  
   }  
   public static Invoice createJsonObject() throws IOException {  
     File f = new File("/home/devbox/workspace/IScreenValidation/src/com/blogspot/javasampleprogram/test.json");  
     ObjectMapper mapper = new ObjectMapper();  
     Invoice invoice = mapper.readValue(f, Invoice.class);  
     return invoice;  
   }  
 }  

Above code is validating the json in 3 steps:

  1. Load json data and use Jackson API to convert it into an Invoice instance
  2. Load validation IScreen configurations
  3. Validate Invoice instance against Iscreen configuration
so if you run the code above you will get the following output:

 Validation Failures found!  

 Invoice Id must be at least 10 and no greater than 100.  
 Invoice Number can be between 1000 and 99999999 and is mandatory  
 Company Name must be at least 10 characters long.  
 Invoice Address is a mandatory field.  
 Quantity can be between 1 and 999999999 and is mandatory  


Please add the following jars to your project:

  1. javassist-3.7.ga.jar
  2. iScreen-ognl-2-0-1.jar
  3. ognl-3.0.jar
  4. jackson-mapper-asl-1.9.5.jar
  5. jackson-core-asl-1.9.5.jar


Friday 5 December 2014

Random Number generator Using Java


Below code generates Random numbers between any two numbers using Java:

 import java.security.SecureRandom;  
 public final class RandomInt {  
   public static final int RANDOM_OFFSET = 256;  
   public static final int RANDOM_LIMIT = 1256;  
   private static final SecureRandom RANDOM = new SecureRandom();  
   private RandomInt() {  
   }  
   public static int random256To1256() {  
     return RANDOM.nextInt(RANDOM_LIMIT - RANDOM_OFFSET) + RANDOM_OFFSET;  
   }  
 }