Wednesday, 14 November 2012

Recursion - propagation of error state

Processing of an arbitrary depth data structure which has a parent or child relation hierarchy seems like a natural candidate for processing recursively.

Processing becomes more complicated when the operation could throw an exception, as we then have to consider how to handle the exception:
  • Should the exception be propagated?
    • Should the caller be expected to be able to reverse any previous state changes?
  • Should the exception be caught and ignored?
    • If so, should we continue to recursively apply the operation?
An alternative approach which may be useful in some situations could be to have a helper object which takes a copy of the outermost starting object and attempts to apply the recursive operation on the copy.  If the operation is successful then the completely transformed copy object can replace the original object.  If the operation was not successful then the original object would remain untouched and the information exposed by the failing operation could be made available to the caller.

I think this may count as a special case of the Unit of Work pattern, where the objects involved are actually part of one composite structure.

From String to enum in Java

Introduction

In the last year or so I have been making more and more use of the enum support in Java to provide reverse lookup from Strings to obtain a value to use in a switch statement.

Example

When iterating over the child nodes of an XML element with a known set of relevant node names and a corresponding process to perform on the differing child node content.


import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;

public enum DwarfNode {
BASHFUL("bashful"), DOC("doc"), DOPEY("dopey"), GRUMPY("grumpy"), HAPPY(
"happy"), SLEEPY("sleepy"), SNEEZY("sneezy");

private String name;

private static final Map lookup
new HashMap();

static {
for (DwarfNode nodeName : EnumSet.allOf(DwarfNode.class)) {
lookup.put(nodeName.name, nodeName);
}
}

public static DwarfNode lookup(String name) {
return lookup.get(name);
}


DwarfNode(String name) {
this.name = name;
}
}


The lookup method takes us from a String to an enum for any recognised name, which can then be used in a switch statement.

When we upgrade to Java 7 - or higher - we will be able to use a String directly in a switch statement, so this approach may become less irrelevant.

Monday, 24 September 2012

Dynamic role-based access control with Spring security

A basic principle of information security is to enforce access restriction at multiple layers.

If we consider a website that presents information from a database:
- The process that handles the request HTTP will not run as a user with admin rights
- The connection to the database will not involve a user with write access to the data

If the information is not intended to be freely available then access can be restricted to logged in users.  If there is more than one level of access restriction then the users can be assigned to roles and the information can be restricted with role-based access control (RBAC).

Role-based access control in a web-based application typically involves specifying URL patterns and roles which should have access to any URLs matching the patterns.  When a request arrives, if there are authentication credentials supplied which match with a specified role then the server will process it and produce a response.

Two common ways to define the pairing between URL patterns and roles are XML and annotations but sometimes making a code or configuration change on the server is too much hassle for the day to day administrators.

In the case of Spring Security, you can set up your own whitelisting by specifying your own AccessDecisionManager with a custom AccessDecisionVoter to allow a secondary check of permission.

Your own AccessDecisionMaker can lookup urls in a database, so there is no need to modify any code or configuration file within the deployed application.

Saturday, 22 September 2012

Apple making up for destructive updates

About a year ago I updated the OS on my iPad without paying enough attention to the ramifications, as a result I a significant amount of music that I had loaded on without syncing to a PC was lost along with several apps that I had downloaded from the AppStore.

This week I was surprised and delighted to find that upon upgrading iTunes on my PC to the latest version, I am now able to see my previous purchases and re-download them from the cloud.

In a few minutes time I hope to re-discover the timewasting delights of two of the Angry Birds series that I have somehow managed to live without for the last 12 months, along with some games that I had purchased but not tried out.

Now I just need to figure out a way of transferring the dozens of albums of music that I have on a PC on the other side of the planet...

Monday, 13 August 2012

Keeping the B in "No BDUF"

Avoiding Big Design Up Front to be flexible for changing requirements and making decisions when you have the most information available is a commonly held principle in eXtreme Programming.

Lately I'm finding myself guilty of ignoring the word "Big", and getting stung by having to go back and make adjustments.


No BDUF != 0 DUF



Sunday, 10 June 2012

BBC iPlayer Desktop Troubleshooting

A few days ago I noticed that the BBC iPlayer application on my laptop would not display the programme listing for downloaded programmes.

I went online to see that several other people have reported the same issue.

Re-installing the application made no difference.

Then I remembered that the external drive which I use for storing media files had disconnected unexpectedly recently, I considered that some files may have been partially written.  Sure enough, when I moved the most recently modified files out of the iPlayer repository the programmes lists started working again.

Update:
Without accidentally disconnecting the drive or shutting anything down in an abrupt manner, my iPlayer installation suffered a repeat of the programmes list problem again.

I'm too busy to bother tracing the exact cause, but if it happens again I will try to isolate what specific download directory is causing this issue.