Posts Tagged: core java


28
Jan 11

Java tricks. Implementing annotations

Say, as it is popular now, you want to have possibility of either static (annotation-based) or dynamic (xml/db-based) configuration of your piece of programming mastership. For instance, your application should support some basic privilege-based security, so, we’ll define @Privilege annotation:

package annotations;
 
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Privilege {
    String code();
}

And a class using it:

@Privilege(code="manage.account")
public class AccountController {}

Abstracting from the details of implementation, the handling of the annotation might look like this:

public class SecurityInterceptor {
 
    public Object intercept(User user, Object controller) {
        annotations.Privilege priv = getPrivilege(controller);
        user.hasPrivilege(priv.code());
    }
 
    protected annotations.Privilege getPrivilege(Object controller) {
        return controller.getClass().getAnnotation(annotations.Privilege.class);
    }
}

Now, we want to be able to configure another controller, OrderController, in a more dynamic way, e.g. by loading the following configuration:

<controller class="OrderController">
    <privilege>manage.account</privilege>
</controller>

So we need to have an object representation for privilege:

public class Privilege {
    public String getCode() { return code; }
    private String code;
}

and a privilege-aware controller:

public class SecuredController {
    public SecuredController(Privilege priv) { this.privilege = priv; }
    public Privilege getPrivilege() { return privilege; }
}
 
public class OrderController extends SecuredController {
    public OrderController(Privilege priv) { super(priv); }
}

See how Privilege and @Privilege are similar? (yeh, I tried to make it obvious ;) )… And in the declaration of annotations.Privilege there is an interface keyword… hm, does it mean we can implement the annotation? Why not! So here we go:

public class Privilege implements annotations.Privilege {
    public String getCode() { return code; }
    public String code() { return getCode(); }
    private String code;
}

And the last stroke is to slightly modify SecurityInterceptor‘s getPrivilege method (of course, being developers of good manners, we shall follow Open-Close Principle):

public class EnhancedSecurityInterceptor extends SecurityInterceptor {
 
    protected annotations.Privilege getPrivilege(Object controller) {
        return (controller instanceof SecuredController) ?
            ((SecuredController) controller).getPrivilege() :
            controller.getClass().getAnnotation(annotations.Privilege.class);
    }
}

Note: the java compiler will threaten you with “Annotation is used as super interface” warning, but you should remain brave and confident!

Moral of the story: reuse code and reduce your maintenance effort!

Feel free to comment, criticise and share your feelings.


27
Jan 11

Java tricks. Extending enumerations

Goal: 1) to have a type that represents a static set of constant values, so we can benefit from the compile-time check… or in less words, an Enum type, 2) to be able to extend the pre-defined set of values in the client class that extends a base client class… ideally, NewEnum extends BaseEnum.

Unfortunately, it’s not possible to extend enum type in Java, because of the enum nature: enum is an ordinal type, which makes it possible to be used in switch operator.

So the solution I’ve come up with is to introduce an interface. Let’s see how it works with the following example.

public interface State {
    String name(); // will be implemeted by java.lang.Enum class
}

public class Entity {
    private State state = ObjectState.CREATED;
    public void setState(State state) { this.state = state; }
    public State getState() { return state; }

    public enum ObjectState implements State {
        CREATED, ACTIVE, DELETED
    }
}

public class Order extends Entity {
    public enum OrderState implements State {
        ACCEPTED, DELIVERED, CANCELLED
    }
}

public class EntityController {
    public void create(Entity entity) { entity.setState(ObjectState.CREATED); }
    public void delete(Entity entity) { entity.setState(ObjectState.DELETED); }
    public void activate(Entity entity) { entity.setState(ObjectState.ACTIVE); }
}

public class OrderController extends EntityController {
    public void accept(Order order) { order.setState(OrderState.ACCEPTED); }
    public void deliver(Order order) { order.setState(OrderState.DELIVERED); }
    public void cancel(Order order) { order.setState(OrderState.CANCELLED); }
}

Pros: both goals achieved, namely we’ve got static constant values and we are not limited by a pre-defined set of values, we can extend it for future use cases.
Cons: there’s no real extensibility of base enum, so we should be aware of the existing base enum before ‘extending’ it, so we don’t repeat values from it.