Thursday, December 25, 2014

How to create your own Unmodifiable List in Java ?

java.util.Collections class offers numerous utility methods, mostly static ones, to operate collection objects effectively.

This class consists exclusively of static methods that operate on or return collections. It contains polymorphic algorithms that operate on collections, "wrappers", which return a new collection backed by a specified collection, and a few other odds and ends. One of the most used utility from this class is unmodifiableCollections or lists.

 So today we will see how we can implement this feature using Java but before we go into more details; let's first understand what unmodifiableList offers to us.

Features:

Like UnmodifiableCollections it returns the wrapper object of the original list which is read-only view of original list. However, important thing to remember here is that it's not immutable list and so state of the object can be changed by modifying original list object.

For ex, any modification made to the original list will be visible to unmodifiable object reference as well.

So now let's see how we can achieve this features by our own custom implementations.

Implementation:

We will need two main classes: MyCollections class to provide the static method which will return our wrapper object and MyUnmodifiableList class which will be the wrapper here to be returned to the caller.

So as it's very much evidant from the API call that unmodifiableList method will be a static method

public class MyCollections {

    public final static  List unmodifiableList(final List list) {
        return (List) new MyUnmodifiableList(list);
    }
}


Since our static method returns the MyUnmodifiableList, we will need concrete implementation of this class. So what do we need from this class ??

1. It should be type of List in order to keep List reference.
2. It should maintain the reference to the original list since we will need to reflect the updates made to the original list.
3. It should not allow any modifications to this object.

So essentially it should behave like the way view does on database table .

To satisfy point #1 here, we will need to implement List interface so class definition will become like this...

public class MyUnmodifiableList implements List {

Now, to get point #2 right,  will need to have List reference in the class;

    List originalList;


Remember, this variable has to keep reference to the originalList and so you might start getting confused now because you kept hearing this whole your life that "java is pass by value and not by reference". Then how on the earth you can keep the reference here to the original List !!

Well, everything you heard is right that Java is pass by value only but in case of objects, it passes the object reference by the value and so any change in original list will still reflect in MyUnmodifiableList reference. Excellent, so we are almost there.....

So last but not least, for point #3, all you need is to keep this class Immutable as the definition says and so what are the methods which can change your object state ??

To name few: add(), addAll(), remove(), removeAll() and few more. Yes, will need to override all of List interface methods here and so you'll need to update it accordingly so that it doesnt support the object state to change.


    public boolean add(E e) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean remove(Object o) {
        throw new UnsupportedOperationException();
    }


So finally we are done now as we have satisfied all of the above conditions and requirements mentioned above for the unmodifiableList interface.

Why I chose this particular example is because it checks lot of core concepts of Java & OOPS. So if you carefully observe this example, it touched upon OOPS (List interface), Program against Interface, Composition over inheritance, Pass by value or reference , Immutable Objects, Exception Handling etc......

If you could implement or understand this example means, you know all of this concepts and  ready to touch upon some more complex examples.

So keep reading.........................................!!!!



Tuesday, December 23, 2014

Java Reflection for Enumerations


Enumerations are pretty handy when it comes to define your own schema for static fields and we all know the power of enumerations so I'm not going to discuss more about enumerations here as you would find many blogs and articles on it.

Today, we are going to discuss the use case where we will need to use enumerations to provide dynamic validations on input fields using reflection and also will see bit more complex example where will need to use reflection to invoke enumeration itself.

Problem Statement: 

Suppose you are receiving the input as CSV file and need to validate all the input fields based on below criteria:
- Field should be validated based on max length.
- Field should be validated based on access types: mandatory or optional.
- Field should be validated based on data type: alphanumeric, numeric (decimal), date etc.

Now, in order to satisfy above requirements, obvious way one would think of is to put if else blocks on each input fields and validate all of above criteria.

Well, nothing wrong with that but it's a old fashioned or rather cruel way of doing things. Java provides many robust features after 1.5 version onwards and we should leverage it.

So, closely observing above requirements you can see we need two static schemas at first: Data type & Access type which can be defined as given below.

public enum DataTypes {
    ALPHANUMERIC, NUMERIC, DATE, STRING;
}


public enum AccessTypes {
    OPTIONAL, CONDITIONAL, MANDATORY;
}

Now using above schema, we want to define the CSV schema for the field validations.

public enum CSVFieldEnumerations {
    ESCROW_ACCOUNT(0, "escrowAccount", "Escrow Account", DataTypes.ALPHANUMERIC, 12 , 0, AccessTypes.MANDATORY),
    CURRENCY(1, "currency", "Currency", DataTypes.ALPHANUMERIC, 3, 0, AccessTypes.MANDATORY),
    PRINCIPAL(2, "principal", "Principal", DataTypes.NUMERIC, 17, 2, AccessTypes.MANDATORY),
    START_DATE(3, "startDate", "Start Date", DataTypes.ALPHANUMERIC, 8, 0, AccessTypes.MANDATORY);


    private int columnNumber;
    private String columnName;
    private String columnDescription;
    private DataTypes columnType;
    private int maxLength;
    private int decimalPlaces;
    private AccessTypes accessType;

    private CSVFieldEnumerations(int columnNumber,
                                    String columnName,
                                    String columnDescription,
                                    DataTypes columnType,
                                    int maxLength,
                                    int decimalPlaces,
                                    AccessTypes accessType) {   
       
        this.columnNumber = columnNumber;
        this.columnName = columnName;
        this.columnDescription = columnDescription;
        this.columnType = columnType;
        this.maxLength = maxLength;
        this.decimalPlaces =  decimalPlaces;
        this.accessType =  accessType;
    }  
 }


Suppose we are using the CSVParser class to read the CSV and validate all input values.JDK provides special Set & Map interfaces to iterate through the enums: EnumSet & EnumMap. We will be using EnumSet here to iterate over the enumerations defined here.

        for (CSVFieldEnumerations schema: EnumSet.allOf(CSVFieldEnumerations.class)) {
Now, lets see how we can utilize the schema to provide the dynamic validations. We will create static methods to access these dynamic properties and provide validations.

    public final static String validateAlphaNumericField(CSVFieldEnumerations column, String value) {
        if(StringValidation.checkLength(value, column.getMaxLength())) {
             if(!StringValidation.isAlphanumeric(column.getColumnName())) {
                 return column.getColumnDescription() + " is not an alphanumeric value";
             } else {
                 return null;
             }
        } else {
            return "Mandatory field " + column.getColumnDescription() + " exceeds size " + column.getMaxLength();
        }
    }


As you can see here, we are accessing the schema values using the enumerations to do validations here.


So we have used the schema to do dynamic validations but we also want to create CSVRecord object from the raw input data and our enumeration will do that as well for us. Remember we have defined columnName in our schema which will be the field name of CSVRecord object.

Reflection:

Field field = CSVRecord.class.getDeclaredField(schema.getColumnName());
setterMethod = CSVRecord.class.getMethod("set" +   StringUtils.capitalize(schema.getColumnName()), (Class) field.getType());
setterMethod.invoke(result, currentColumn.trim());


So here we will iterate through the EnumSet for each enumeration constants defined in the schema and will validate based on the metadata defined along with setting up the CSVRecord Object.  

So two birds with single stone !!
This is the power of Enumeration when combined with Reflection.

Reflection to load Enumerations:

Now, let's make above example bit more complex and consider the scenario where you need one more layer to load enumerations itself using the reflection.

Say, you have 4 different CSVs to parse and prepare common CSVRecord to send out as XML. so one will say what's the big deal, I'll set the CSV type in the parser and then will use  that to load enumeration and then iterate it over using EnumSet like we did above.

Well, here is the catch, while you fetch the enumeration using EnumSet.allOf(), you need to cast it to perticular enumeration but here you don't have any type to cast unless you do it in if else blocks for each enumeration defined for the CSV type because Enumerations cannot subclassed and so you dont' have supertype here.

Well, alternately you can use generics to load enumerations using the reflection as given here.

        Class enumClass = Class.forName("com.csv." + this.csvTypes);
        Object[] enumConstants = enumClass.getEnumConstants();

        for (int i = 0; i < enumConstants.length; i++) {
            Class sub = enumConstants[0].getClass();              
            enumColumnName = sub.getDeclaredMethod("getColumnName");
            columnNameValue = String.valueOf(enumColumnName.invoke(enumConstants[i]));
          .

          .
          .
          .
         
 So, here we are using '?' since we don't know the type of the returned enumeration but still able to invoke the getters on the enum properties to achieve the desired results !!

Hope, this will help you understand enumerations and refection concepts.

so happy reading......