Hollywood Principle – translated

For as long as dependency injection gained its popularity (starting with Spring, then followed by Java EE, etc), people have always associated DI with Hollywood Principle – Don’t call us, we’ll call you.

Yet, perhaps it’s just my own ignorance, I have never found any direct translation as to why dependency injection is “Don’t call us, we’ll call you”. Even during some interviews, I have heard quite a number of people being asked, What do you know about Hollywood Principle?. The answer generally follows the line of:

  • “It’s dependency injection, period”, or
  • “It’s like Spring where by your objects are instantiated with its dependencies, period”.

I have never really found a satisfactory explanation, until today.

Therefore, perhaps more for my own reference, with the hope that those who are as confused as I was previously would find this post beneficial, the best explanation I found is from one of the post by Andrew Binstock (2008). Following is one of the paragraphs I found from the author’s post that I paraphrased.

“Dependency Injection was originally called Inversion of Control (IoC) because as opposed to the normal control sequence where an object finds the objects it depends on by itself, and then calls them, in IoC it is reversed. The dependencies are handed to the object when it’s created. This also illustrates the Hollywood Principle at work: Don’t call around for your dependencies, we (in this case the IoC container/runtime) will give them to you when we need you(Binstock 2008).

Reference:

Binstock, A, 2008, Binstock on Software: Excellent Explanation of Dependency Injection (Inversion of Control), accessed 22 March 2012.

Cross-field validation using Bean Validation (JSR 303)

I recently introduced the use of Bean Validation in one of the project I was working on. At the very start, it was just a complete experiment with a very “defensive” implementation, with the mindset that if the use of this API proved to be problematic, it would be thrown away.

Turned out to be a very good set of API, and it is very enjoyable to use.

It is true that there are things to read, learn and experiment (here, unit testing helps A LOT) and the site from JBoss helped a lot.

Amongst the many things I learnt, one of the immediate requirement I encountered was the ability to implement a cross-field validation. I suppose it is understandable as to why the cross-field validation is not part of the standard API. Why how would one standardise such case with so many variations/approaches, etc. I am sure though that the JSR team will eventually address it.

That being said, Bean Validation allows flexibility via the use of Custom Validator and with that, cross-field validation can be implemented. The example that I used in this entry today is based on the post in stackoverflow.com by user Nicko (Nicko 2010).

Supposed there is an entity called Purchase. A Purchase must be allocated to correct authorisation department, and also payment department. For a Purchase to be considered valid, it must also be authorised by a person from that authorisation department, and paid by someone from the payment department. (This might be a silly example, but you’ll get the intention)..

Using the example from stackoverflow.com, the classes are:

EnrolmentValid

package com.wordpress.dwuysan;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

/**
 * @author dwuysan
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnrolmentValidator.class)
public @interface EnrolmentValid {

    String message() default "{com.wordpress.dwuysan.EnrolmentValid.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    String personNoFieldName();

    String departmentNoFieldName();

    @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @interface List {
        EnrolmentValid[] value();
    }
}

EnrolmentValidator

package com.wordpress.dwuysan;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import org.apache.commons.beanutils.BeanUtils;

/**
 * @author dwuysan
 */
public class EnrolmentValidator 
        implements ConstraintValidator<EnrolmentValid, Object> {

    private String personNoFieldName;
    private String departmentNoFieldName;

    @Override
    public void initialize(final EnrolmentValid a) {
        this.personNoFieldName = a.personNoFieldName();
        this.departmentNoFieldName = a.departmentNoFieldName();
    }

    @Override
    public boolean isValid(
                final Object t, final ConstraintValidatorContext cvc) {
        final Object personNo;
        final Object departmentNo;
        try {
            personNo = BeanUtils.getProperty(t, 
                this.personNoFieldName);
            departmentNo = BeanUtils.getProperty(t,
                this.departmentNoFieldName);
            /* Validation logic goes here */
        } catch (final Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }

        if (personNo == null || departmentNo == null) { return true; }

        // return false, just to make it always fail
        return false;
    }
}

Purchase

package com.wordpress.dwuysan;

import javax.validation.constraints.NotNull;

/**
 * @author dwuysan
 */
@EnrolmentValid.List(value = {
    @EnrolmentValid(
        personNoFieldName = "authorisePersonNo", 
        departmentNoFieldName = "authorisationDepartmentNo", 
        message="Authoriser does not belong to the auth department"),
    @EnrolmentValid(
        personNoFieldName = "payerPersonNo", 
        departmentNoFieldName = "paymentDepartmentNo", 
        message="Payer does not belong to the payment department")
})
public class Purchase {

    private Integer authorisePersonNo;
    private Integer payerPersonNo;

    @NotNull
    private Integer authorisationDepartmentNo;
    
    @NotNull
    private Integer paymentDepartmentNo;
    
    /* accessor/mutator methods not shown */
}

Have tried this approach and it worked perfectly. However, if then we were to refactor the fields, say in this case the names of the properties are too long and it should be changed to authPersNo and , then this example would fail (again, of course JUnit will pick this up).

ALTERNATIVE APPROACH

The other option is to actually remove the use of “reflection”, and instead, use an additional class just exposing those fields to be validated.

EnrolmentValidation

package com.wordpress.dwuysan;

/**
 * @author dwuysan
 */
public final class EnrolmentValidation {
    private final Integer personNo;
    private final Integer departmentNo;

    public EnrolmentValidation(
            final Integer personNo, 
            final Integer departmentNo) {
        this.personNo = personNo;
        this.departmentNo = departmentNo;
    }

    public Integer getDepartmentNo() {
        return departmentNo;
    }

    public Integer getPersonNo() {
        return personNo;
    }
}

Then change the Validator to directly access the fields (instead of using reflection).

EnrolmentValidator

package com.wordpress.dwuysan;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * @author dwuysan
 */
public class EnrolmentValidator 
        implements ConstraintValidator<EnrolmentValid, EnrolmentValidation> {

    @Override
    public void initialize(final EnrolmentValid a) {}
    
    @Override
    public boolean isValid(
                final EnrolmentValidation t, 
                final ConstraintValidatorContext cvc) {
        if (t.getPersonNo() == null || t.getDepartmentNo() == null) {
            return true;
        }
        /* Validation logic goes here */

        // return false, just to make it always fail
        return false;
    }
}

Also, change the annotation by removing the field names.

EnrolmentValid

package com.wordpress.dwuysan;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

/**
 * @author dwuysan
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnrolmentValidator.class)
public @interface EnrolmentValid {

    String message() default "{com.wordpress.dwuysan.EnrolmentValid.message}";

    Class[] groups() default {};

    Class[] payload() default {};

    // String personNoFieldName();

    // String departmentNoFieldName();

    @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @interface List {
        EnrolmentValid[] value();
    }
}

THEN, the problematic one is the Purchase class itself. For a start, we could simply add methods returning EnrolmentValidation object, with the method annotated with @EnrolmentValid

Purchase

package com.wordpress.dwuysan;

import javax.validation.constraints.NotNull;

/**
 * @author dwuysan
 */
public class Purchase {

    private Integer authorisePersonNo;
    private Integer payerPersonNo;

    @NotNull
    private Integer authorisationDepartmentNo;
    
    @NotNull
    private Integer paymentDepartmentNo;

    @EnrolmentValid
    public EnrolmentValidation getAuthPersonDepartmentEnrolmentValidation() {
        return new EnrolmentValidation(
            this.authorisePersonNo, 
            this.authorisationDepartmentNo);
    }

    @EnrolmentValid
    public EnrolmentValidation getPayerDepartmentEnrolmentValidation() {
        return new EnrolmentValidation(
            this.payerPersonNo,
            this.paymentDepartmentNo);
    }

    /* accessor/mutator methods not shown */
}

That works as expected. However, it may not be the most ideal scenario since the class Purchase is now “polluted” with validation specific methods. Also, some prefer clear separation between the domain model and its validation. One way to achieve this is to use interface (and an Adapter class).

Please refer to the following interface.

PurchaseValidation

package com.wordpress.dwuysan;

import javax.validation.constraints.NotNull;

/**
 * @author dwuysan
 */
public interface PurchaseValidation {

    @NotNull
    Integer getPayerPersonNo();

    @NotNull
    Integer getPaymentDepartmentNo();

    @NotNull
    Integer getAuthorisePersonNo();

    @NotNull
    Integer getAuthorisationDepartmentNo();

    @EnrolmentValid
    EnrolmentValidation getAuthPersonDepartmentEnrolmentValidation();

    @EnrolmentValid
    EnrolmentValidation getPayerDepartmentEnrolmentValidation();
}

I supposed the way to look at it is to say, “Here is the list of validations relating to Purchase“. And so that the class Purchase is not tainted with validation logic, create a simple Adapter class as follows.

PurchaseValidationAdapter

package com.wordpress.dwuysan;

/**
 * @author dwuysan
 */
public class PurchaseValidationAdapter implements PurchaseValidation {
    private final Purchase purchase;

    public PurchaseValidationAdapter(Purchase purchase) {
        this.purchase = purchase;
    }

    @Override
    public Integer getPayerPersonNo() {
        return this.purchase.getPayerPersonNo();
    }

    @Override
    public Integer getPaymentDepartmentNo() {
        return this.purchase.getPaymentDepartmentNo();
    }

    @Override
    public Integer getAuthorisePersonNo() {
        return this.purchase.getAuthorisePersonNo();
    }

    @Override
    public Integer getAuthorisationDepartmentNo() {
        return this.purchase.getAuthorisationDepartmentNo();
    }

    @Override
    public EnrolmentValidation getAuthPersonDepartmentEnrolmentValidation() {
        return new EnrolmentValidation(
                this.purchase.getAuthorisePersonNo(),
                this.purchase.getAuthorisationDepartmentNo());
    }

    @Override
    public EnrolmentValidation getPayerDepartmentEnrolmentValidation() {
        return new EnrolmentValidation(
                this.purchase.getPayerPersonNo(),
                this.purchase.getPaymentDepartmentNo());
    }
}

CONSIDERATIONS

I suppose the alternative approach presented here removes the use of “reflection”, and at the same time introduces the separation between the validation layer and the actual business domain model. Using Adapter, we can also adapt other models into a single validation layer. For example, when dealing with a legacy code, an application may have multiple class representing the very same business object. In this case, perhaps consider a class like PurchaseSummary, PurchaseLite, etc. This alternative approach, however, does introduce more code.

I am sure that people who have used JSR-303 have also encountered the need of cross-field validation. I am interested to know their thoughts and any comment to this post is very welcomed.

References:
Nicko, 2010, Cross field validation with Hibernate Validator (JSR 303), accessed 20 March 2012.

[ERROR] Two declarations cause a collision in the ObjectFactory class

This issue, and its workaround, has been identified by the Unofficial JAXB Guide – Dealing with errors (Project JAXB 2012).

When one of my colleagues and I faced this issue, we still had to spend some amount of time trying to “understand” why, and how to fix it. I thought I’ll share some examples and findings so that in the future people can easily resolve it.

To start with, the error occur because the same name between a TYPE and an ELEMENT. Please refer to the following XML snippet. (The example that is used here is based on the XSD obtained from Personal Property Securities Register).

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://schemas.ppsr.gov.au/2011/04/data" 
    elementFormDefault="qualified" 
    targetNamespace="http://schemas.ppsr.gov.au/2011/04/data" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <!-- The rest of the code removed -->

    <xs:complexType name="GrantorOrganisation">
        <!-- Content removed -->
    </xs:complexType>
    <xs:element name="GrantorOrganisation"
        nillable="true" type="tns:GrantorOrganisation" />

    <!-- The rest of the code removed -->
</xs:schema>

Notice that the GrantorOrganisation is used as the name for both name and type, hence the collision.

To resolve this, use the JAXB binding and modify the objectFactory method name. Please refer to the bindings.xjb below:

<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
          xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
          xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
          xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd" version="2.1">
    <globalBindings>
        <serializable uid="1" />
    </globalBindings>
    <bindings schemaLocation="schemas.ppsr.gov.au.2011.04.data.xsd">
        <bindings node=".//xs:element[@name='GrantorOrganisation']">
            <factoryMethod name="GrantorOrganisationElement" />
        </bindings>
        <!-- rest of the code remove, need to do it for every collision -->
    </bindings>
</bindings>

Some findings:

  • I was under impression that since it is collision, I can also bind the type instead. So the node will be node=".//xs:complexType[@name='GrantorOrganisation']". That did NOT work.
  • Since the node argument has the prefix xs:, also need to add the xs in the declaration of my binding file (Even thought I did not use it anywhere else).

P.S. Many thanks to George Gao for sharing the solution.

References:

Project JAXB, 2012, ‘Unofficial JAXB Guide – Dealing with errors’, accessed 08 March 2012.

Personal Property Securities Register, 2012, Accessing the PPSR Business to Government (B2G) Channel, accessed 08 March 2012.