Kotlin – Use EnumSet For RBAC

Enumset is a powerful collection in Java to replace bit fields.

This article will explains how to use EnumSet to create a RBAC (Role-Based Access Control).

User.kt
import java.util.*

class User (val access: EnumSet<Access>)
Access.kt
enum class Access {
    NONE, VIEW, COMMENT, EDIT
}

Now, let’s see how we can use EnumSet to create a RBAC.

UserTest.kt
import org.junit.jupiter.api.BeforeEach
import java.util.*
import kotlin.test.assertFalse
import kotlin.test.assertTrue

internal class UserTest {
    var adminRoles       = EnumSet.noneOf(Access::class.java)
    var superUserRoles   = EnumSet.noneOf(Access::class.java)
    var basicUserRoles   = EnumSet.noneOf(Access::class.java)
    var visitorRoles     = EnumSet.noneOf(Access::class.java)

    @BeforeEach
    fun setup(){
        this.adminRoles     = EnumSet.allOf(Access::class.java)
        this.superUserRoles      = EnumSet.complementOf(EnumSet.of(Access.EDIT))
        this.basicUserRoles      = EnumSet.of(Access.VIEW)
        this.visitorRoles        = EnumSet.of(Access.NONE)
    }

    @org.junit.jupiter.api.Test
    fun getAccess() {
        val admin       = User(adminRoles)
        val visitor     = User(visitorRoles)
        val basicUser   = User(basicUserRoles)

        assertTrue(admin.access.containsAll(adminRoles))
        assertFalse(visitor.access.containsAll(adminRoles))
        assertFalse(basicUser.access.containsAll(adminRoles))
        assertTrue(basicUser.access.containsAll(basicUserRoles))
    }
}

Inside the setup method, a series of roles with specific access right in a given system has been defined

In User class, there is a property which its’ type is an EnumSet. This indicates that, every instance of User has its roles.

Use containsAll method of Java Collections to test against, whether an instance of user match a certain roles, with this we can give an instance of user of specific right to access in our system, based on the boolean result returned by containsAll

Source Codes: https://github.com/wuchiachong/kotlin-EnumSet

Java – Why you should use Optional

To Overcome NullPointerException

The Java 8’s Optional is meant for alleviating the occurrence of NullPointerException. NullPointerException is the result of Null References, Null Reference is also known as The Billion Dollar Mistake.

The Billion Dollar mistake was coined by a British computer scientist,
Sir Charles Antony Richard Hoare.

Null pointers are the single biggest source of bugs in programs. Without them, all of the time wasted tracking down those bugs can be spent on more productive things, therefore it is known as The Billion Dollar mistake coined by a British computer scientist, Sir Charles Antony Richard Hoare.

References:

Java Optional

Java – How to compare strings

== is to compare 2 object whether are of the same reference equality (whether they are the same object).

.equals() tests for value equality (whether they are logically “equal”).

Objects.equals() checks for null before calling .equals() so you don’t have to check null to avoid NPE. (available since JDK7, also available in Guava).

String.contentEquals() compares the content of the String with the content of any CharSequence (available since Java 1.5).

To test whether two strings have the same value the best way to use isObjects.equals().

// These two have the same value

new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

You almost always want to use Objects.equals(). In the rare situation where you know you’re dealing with interned strings, you can use ==.

Java – What are Default Methods II

Prior to Java 8, Java interfaces cannot be implemented. Because of a class can implement more than 1 interface, and imagine in the event of there is same signature in different interfaces which the class is implementing, then in this case, the class might be confused to picking which one, cause in the past prior to Java 8, there was no rule in compiler to determine, which interface’s method should be picked.

Multiple Interface Inheritance Rules

Java compiler provides some rules to determine which default method a particular class uses.

1. Instance methods are preferred over interface default methods.

If a class extends another class and other interfaces, where the parent class and the interfaces co-incidentally have the same signature. Then the parent class’s signature will be chosen rather than the interfaces’ one.

Result: Process finished with exit code 0

2. Methods that are already overridden by other candidates are ignored

The move() of Combustion is overridden by Turbo‘s one, therefore the Turbo‘s move() is chosen.

Source Codes

GitHub

Java – How to Handle NullPointerException Effectively

NullPointerException is a common exception in Java-based applications. It is also known as Billion-Dollar mistake. NullPointerException is a sub-class of RuntimeException.

A RuntimeException is an unchecked exception, it does not force you to use catch block to handle it. This article going to explain some approaches to handle NullPointerException effectively.

Why NullPointerException occur in your code

Before looking into approaches, let’s get to know why NullPointerException happens.
NullPointerException is thrown when an application attempts to use null in a case where an object is required. These include:

  • Calling the instance method of a nullobject.
  • Accessing or modifying the field of a nullobject.
  • Taking the length of nullas if it were an array.
  • Accessing or modifying the slots of nullas if it were an array.
  • Throwing nullas if it were a Throwable value.

A nullobject is an object which has not been initialized yet.

UserServiceTest.Java
import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class UserServiceTest {

	@Test
	void whenExceptionThrown_thenAssertionSucceeds() {
		String userName = null;
		assertThrows(NullPointerException.class, () -> {
			userName.length();
		});
	}

}

The above unit test method whenExceptionThrown_thenAssertionSucceeds() is pass. The unit test expected NullPointerException to be thrown, because of the code is accessing length() method on a nullobject.

Where normally Java NullPointerException Occurs

    1. Invoking methods on an object which is null or not initialized.
    2. Using synchronized on an object which is null
    3. Chained statements i.e. multiple method calls in a single statement

Guides to handle NullPointerException

Solution#1 Use Java Libraries e.g. Apache Common Lang and Google Guava

Solution#2 Use ternary operator to check value. If the value is null then assign a default value, otherwise evaluate the value.

Apache Common’s StringUtils.isNotEmpty()
if (StringUtils.isNotEmpty(obj.getStringValue())){
    String s = obj.getStringValue();
    ....
}
Google Guava’s Strings.isNulllOrEmpty()
if (Strings.isNulllOrEmpty(obj.getStringValue())){
    String s = obj.getStringValue();
    ....
}
Android’s TextUtils.isEmpty()
if (TextUtils.isEmpty(obj.getStringValue())){
    String s = obj.getStringValue();
    ....
}

Solution#3 Always put input validation at the beginning of your method so that the rest of your code does not have to deal with the possibility of incorrect input. So if someone passes in a null, things will break early in the stack rather than in some deeper location where the root problem will be rather difficult to identify.

Aiming for fail fast behavior is a good choice in most situations.

Solution#3 You should always put input validation at the beginning of your method so that the rest of your code does not have to deal with the possibility of incorrect input. So if someone passes in a null, things will break early in the stack rather than in some deeper location where the root problem will be rather difficult to identify.

Solution#4
Null problem occurs where object references points to nothing. So always use primitives as much as possible because they does not suffer with null references. All primitives must have some default values also attached so beware of it.

Solution#5 While readability of fluent interface or chained method are good, however they are not NPE friendly. A single statement spread over several lines will give you the line number of the first line in the stack trace regardless of where it occurs.

objectRef.method1().method2().method3().methods4();

These kind of chained statement will print only “NullPointerException occurred in line number xyz”. It is pain in the bug to debug such code. Please avoid such calls.

Solution#6 Use String.valueOf() Rather than toString(). Even if object is null in String.valueOf(null) , it will not give exception and will prints ‘null’ to output stream.

#Solution#7 In stead of writing below code for string comparison

public class SampleNPE {
   public void demoEqualData(String param {
      if (param.equals("check me")) {
         // some code
      }
   }
}

write above code like this. This will not cause in NPE even if param is passed as null.

public class SampleNPE {
   public void demoEqualData(String param) {
      if ("check me".equals(param)) // Do like this
      {
         // some code
      }
   }
}

Solution#8 An awesome tip to avoid NPE is to return empty strings or empty collections rather than a null. Do this consistently across your application. You will note that a bucket load of null checks become unneeded if you do so.

An example could be:

List data = null;
@SuppressWarnings("unchecked")
public List getDataDemo()
{
   if(data == null)
      return Collections.emptyLists(); //Returns unmodifiable list
   return data;
}

Users of above method, even if they missed the null check, will not see ugly NPE.

Java – What are Default Methods I

Java 8 brought a new capability known as default methods into Java interface. This articles guides you how to get the benefit from default methods in interface.

Why Default Methods in Interfaces Are Needed

Imagine in a situation where if one or more methods are added to the interface, then classes which implemented those interfaces would have to rewrite their implementations. Prior to the introduction of default methods capability in interface, there is this soi-disant “Extended Interface” to resolve the above-mentioned problem.

Default methods enable programmers to add new functionality to the interfaces of your libraries that are automatically available in the implementations. In this way, backward compatibility is neatly preserved without having to refactor classes which implemented the going-to-be-modified interface.

Default Interface Methods in Action

Vehicle.java
package com.cloudberry.my;

public interface Vehicle{
	String getBrand();

	String speedUp();

	String slowDown();

	default String turnAlarmOn() {
		return "Turning Vehicle alarm on.";
	}

	default String turnAlarmOff() {
		return "Turning Vehicle alarm off.";
	}
}

There are 2 default methods namely turnAlarmOn() & turnAlarmOff() in interface Vehicle.

Bus.java
package com.cloudberry.my.action;

import com.cloudberry.my.Vehicle;

public class Bus implements Vehicle{

	@Override
	public String getBrand() {
		return "Alex Dennis";
	}

	@Override
	public String speedUp() {
		return "200kmph";
	}

	@Override
	public String slowDown() {
		return "0kmph";
	}
}

Because of class Bus implements the interface Vehicle , therefore turnAlarmOn() & turnAlarmOff() are automatically provided by interface Vehicle.

BusTest.java
package com.cloudberry.my.action;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

import com.cloudberry.my.Vehicle;

class BusTest {

	@Test
	void testBus() {
		Bus bus = new Bus();
		assertEquals("Turning Vehicle alarm off.", bus.turnAlarmOff());
	}
	
	@Test
	void testVehicle() {
		Vehicle bus = new Bus();
		assertEquals("Turning Vehicle alarm off.", bus.turnAlarmOff());
	}

}

FYI, the above unit-test results are pass. Even though Bus does not have turnAlarmOff() method, but because of Bus implements interface Vehicle which the interface marks the turnAlarmOff() as default method, thus every instance of Bus contains the default methods which it implements from.

References

Java Default Methods

Python – Zen of Python

  1. Beautiful is better than ugly.
  2. Explicit is better than implicit.
  3. Simple is better than complex.
  4. Complex is better than complicated.
  5. Flat is better than nested.
  6. Sparse is better than dense.
  7. Readability counts.
  8. Special cases aren’t special enough to break the rules.
  9. Although practicality beats purity.
  10. Errors should never pass silently.
  11. Unless explicitly silenced.
  12. In the face of ambiguity, refuse the temptation to guess.
  13. There should be one—and preferably only one—obvious way to do it.
  14. Although that way may not be obvious at first unless you’re Dutch.
  15. Now is better than never.
  16. Although never is often better than right now.
  17. If the implementation is hard to explain, it’s a bad idea.
  18. If the implementation is easy to explain, it may be a good idea.
  19. Namespaces are one honking great idea—let’s do more of those!

Java – Use Annotation to create Custom Constraint

Imagine, given a situation where you want to check if a required String field whether has emptied value or not. The simplest way is to use if keyword to check whether a given field which its type is String whether is emptied or null.

if (("").equals(userModel.getFirstName())){
    ......
}

In addition to the above-mentioned method, one can use annotation to do validation.

  1. Create a Custom Annotation
  2. Required.java
    import java.lang.annotation.*;
    
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Required {
    
    }
  3. Create a Java Bean
  4. UserModel.java
    import java.io.Serializable;
    
    public class UserModel implements Serializable {
    
    	private static final long serialVersionUID = -4469704917708123018L;
    
    	private long id = 0;
    	
    	private String firstName = "";
    	
    	@Required
    	private String lastName = "";
    	
    	public long getId() {
    		return id;
    	}
    	public void setId(long id) {
    		this.id = id;
    	}
    	public String getFirstName() {
    		return firstName;
    	}
    	public void setFirstName(String firstName) {
    		this.firstName = firstName;
    	}
    	public String getLastName() {
    		return lastName;
    	}
    	public void setLastName(String lastName) {
    		this.lastName = lastName;
    	}
    }
    

    In this example, I m going to make onlylastName as a required field. Which means the value of lastName should not be emptied.

  5. A Repository Class which contains Validator
  6. UserRepository.java
    import java.lang.reflect.Field;
    
    public class UserRepository {
    	public static void register(UserModel userModel, ValidationMode validationMode) {
    		if (null  == userModel) {
    			return;
    		}
    		if (validationMode == ValidationMode.BRANCHING) {
    			validateWithBranching(userModel);
    		}
    		
    		if (validationMode == ValidationMode.ANNOTATION) {
    			validateWithAnnotation(userModel);
    		}
    		
    	}
    	
    	public static void validateWithBranching(UserModel userModel) {
    		if (("").equals(userModel.getFirstName())) {
    			throw new IllegalArgumentException("First Name is required");
    		}
    		
    		if (("").equals(userModel.getLastName())) {
    			throw new IllegalArgumentException("Last Name is required");
    		}
    	}
    	
    	public static void validateWithAnnotation(UserModel userModel) {
    		final Field[] modelFields = userModel.getClass().getDeclaredFields();
    
            for (Field modelField : modelFields) {
            	if (modelField.isAnnotationPresent(Required.class)) {
            		modelField.setAccessible(true);
            		try {
            			String value = (String) modelField.get(userModel);
            			if ("".equals(value)) {
                            throw new IllegalArgumentException(modelField + " is required");
            			}
            		}
            		catch(IllegalAccessException  ex) {
            			ex.printStackTrace();
            		}
            	}
            }
    	}
    	
    }
    

    The main points of this class I would like to emphasize are the following:

    • userModel.getClass().getDeclaredFields()the getClass method returns an instance of Class, which has a method called getDeclaredFields that returns all attributes (even private) of this class.
    • modelField.isAnnotationPresent(Required.class)as the method name explains, this is where it’s verified the presence of the Required annotation for each attribute of the model being validated.
    • modelField.setAccessible(true)this makes a private field accessible, meaning we can read or change itsvalue.
    • modelField.get(userModel)it returns the value of the modelField attribute in any object instance
  7. Testing the codes
  8. UserRepositoryTest
    import static org.junit.jupiter.api.Assertions.assertThrows;
    
    import org.junit.jupiter.api.BeforeAll;
    import org.junit.jupiter.api.Test;
    
    
    class UserRepositoryTest {
    	static UserModel userModel;
    	 	
    	@BeforeAll
    	static void init() {
    		userModel = new UserModel();
    	}
    	
    	@Test
    	void testValidateWithBranchingMissingValue() {
    			
    		assertThrows(IllegalArgumentException.class, () -> {
    			UserRepository.register(userModel, ValidationMode.BRANCHING);
    	    });	
    	}
    	
    	@Test
    	void testValidateWithAnnotationMissingValue() {
    		
    		assertThrows(IllegalArgumentException.class, () -> {
    			UserRepository.register(userModel, ValidationMode.ANNOTATION);
    	    });	
    	}
    
    }

References

Java Custom Annotations
Java Reflection API

Source Codes

GitHub