Introduction (OOP principles)

Today I’d like to present you a problem that most especially rookie developers find compelling. This is strongly connected with OOP basics, specifically with 2 fundamental truths:

  1. Use inheritance whenever possible.
  2. Prefer composition over inheritance.
So at first I had problems understanding how these 2 rules are related but as the time passed I learned to distinguish the two and recently in one of my projects I came across piece of code that is perfect example on why object composision/aggregation might be a better solution over inheritance.

Old way – using inheritance

Background – code usage

To start with some background – the code referred to is part of application that displays daily trend graph of some piece of data. It’s responsible for drawing coordinate system, x-axis, y-axis, some labels, legend lines, text-labels and of course data-curves. The code is executed on client-side and one of requirements is to support ie8 – which is why there was a need to support both SVG and VML drawing formats.

Classes responsibilites

The old apporach used in inheritance to support both formats and below you can find class diagram for the described classes. To start from the top:

  • GrapDrawer is a drawing interface – it’s main goal is to provide high-level methods for drawing different parts of graph used by othere pieces of application
  • AbstractGraphDrawer which is an interesting beast – because it provides a bridge between GraphDrawer interface and client-specific implementations – that is VML/SVG achieved set of abstract protected methods that encapsulate client-specific drawing API
  • SVGDrawer/VMLDrawer – these are both client-specific drawing apis.

Problem description

You might be asking yourselves why is there any problem with this approach. It has all the good parts:

  • there’s an interface for accessing public methods,
  • there’s an abstract method that acts as a bridge between drawer and
  • client-specific implementation.

Everything is encapsulated so user has no knowledge of what’s going on behing the secenes – so what’s the big deal.

This is all true but due to AbstractGraphDrawer dual nature it’s code is really hard to maintain. Both high and low-level API collide with each other – the former changes frequently where the latter very rarely. If you look closer you can see that all protected methods are there only to be overridden by implementation and they’re completely hidden from user. While all parts of public interface are not used in any way by the implementation.

New way – use object aggregation

Solution description

These two worlds interact with each other only through their interfaces. So it’s a perfect candidate for split – low-level methods should be hidden behind an interface that must be implemented by client-specific code, whereas high-level methods, used by some other code go to a public class which has reference to client-specific low-level drawing api.

This is all presented in the diagram below, where you can find:

  • GrapDrawer class which is used for high-level operations. Low level operations are executed by graphDrawerWorker
  • GraphDrawerWorker interface which defines set of required low-level operations
  • SVGDrawer/VMLDrawer classes which only implement GraphDrawerWorker and thus loose all coupling with high-level code

Summary

There’s still at least one question that needs some attention: how did this code creep into the application? The answer is fairly simple – it was built incrementally as business needs rose and suddenly AbstractGraphDrawer became a beast with two heads. Unfortunately for everyone who’s been working with it for longer time it was hidden. Only when someone with fresh look apporached a project, not only could this be spotted but also addressed.

All of you that can spot more basic OOP principles broken in original code (or a new one :P) please leave them in comments 🙂

This blog is a contitunation of my previous entry (polish only sorry) in which I presented a solution for hiding certain operations on a collection using jdk’s dynamic proxy mechanism. It consited of MethodInterceptr which checked if specific method was called and in such a case it reported and error using RuntimeException.

With this entry I’d like to present a different approach using google collection ForwardingObjects. It’s parent for all types of wrappers – one for each collection type and the advantage of using wrapper is that hey’re all designed as abstract classes implementing interface for given type of Collection, in case of Set it’s ForwardingSet (to continue older example) and the only thing you need to do as implementor is to telli wrapper how it can find its delegate by providing a delegate method.

Below you can find previous example rewritten to use ForwardingSet with disabled clear method. Last but not least – this version is waaay much cleaner 🙂 and you also let compiler do its job – if you check the previous post you’ll notice that there are two versions of this solution. The original one contained a but because I made a typo and the code checks for call to clean method instead of clear…

import java.util.Set;
import com.google.common.collect.ForwardingSet;

class StructElement3 {

	private class ForwardingSetNoClear extends ForwardingSet<String> {

		private Set<String> delegate;
		public ForwardingSetNoClear(Set<String> delegate) {
			this.delegate = delegate;
		}

		@Override
		protected Set<String> delegate() {
			return delegate;
		}

		@Override
		public void clear() {
			throw new UnsupportedOperationException("Cannot call clear");
		}
	}

	public StructElement3(Set<String> obj) {
		Set<String> forwardingSet =  new ForwardingSetNoClear(obj);

		// yeah yeah keep talking...
		forwardingSet.clear();
	}

}

Problem description

There is a part of your application that needs to display summaries of certain piece of data stored in data base and you need to specily  certain intervals for which summaries should be retrieved.

Requirements

I want to have an easy way of fetching summaries for some columns in certain table for specified interval.

Solution description

Plain SQL

The first solution that comes into play is glue some pieces of SQL together from sum and execute it – yes it’s fast, it works but it’s ugly.

Use HQL

Yes in this solution we’ve got some of the job perfomed by Hibernate – we’ve got our entity defined, there’s a bridge for each sql dilatect but… we still need to explicitly state columns and add calls to sum function in order to retrieve summaries.

Entity to Criteria mapping

But maybe we could somehow use the same Entity object that we have already defined for this specific table and instead of performing regular fetch, generate sql based on @Column definitions. That way we are able to use JavaBean property name as alias for sum and use result transformer to get the data back.

The only portion that’s left here is adding support for omitting some properties – we don’t want to do automated retrieval of SUM’s for name or id 🙂

Source code

Solution consists of 2 static methods responsible for:

There’s also 3rd method but it’s totally optional – it prevents NPE for returned values of a specifc type and it uses cglib-jdk5 Enhancer, so you don’t need to do explicit casting 🙂

You can see full source code on github.

As you can see title of this entry is not very descriptive but the idea is to save some of you folks couple of hours (this is how I’ve been trying to find some pieces of information).

So the problem is pretty well described under this entry on seam forum but just to give you an idea:

  • you have a list of integer wrappers (List<Integer>)
  • you pass this list to your jsf view
  • some component goes through entries in the list (rich:datatable in my case)
  • all entries are displayed as h:inputText and value is assigned using name given in var attribute
  • each input text has an onblur event attached that re renders the whole element (rich:datatable)

The expected behaviour is that newly entered value is bound and displayed again in the form but this is not happening.

The solution is described here – basically assigning value using name given in var attribute is not bi-directional, so you need to use indexing technique.

 

Below you can find source code for effect named Clownfish. Probably some of you will scratch your heads when seeing this name but for me watching how these bubles avoid cursor is similar to how small clownfish finds shelter in stinging tentacles of the anemone.

You can find it in action at this website (circles over top menu).

/**
 * Copyright (c) 2011, Marek Bedkowski
 * All rights reserved.
 *
 * @author Marek Bedkowski
 * @package pl.bedkowski.code.clownfish
 * @license new BSD License (https://github.com/bendi/code/blob/master/zend_form_decorator_js_validation/LICENSE)
 *
 */
package pl.bedkowski.code.clownfish
{
	import flash.display.MovieClip;
	import flash.events.Event;

	public class ClowFishBall extends MovieClip
	{
		private var distance:Number,startX:Number = 0,startY:Number = 0,speed:Number = 0;

		private static var DISTANCE:Number = 3000;

		private static var FILL_COLOR:Number = 0x13698F;

		public function ClowFishBall(_x:Number, _y:Number, radius:Number)
		{
			graphics.beginFill(FILL_COLOR);
			graphics.drawCircle(0,0,radius);
			graphics.endFill();

			startX = x = _x;
			startY = y = _y;

			speed = (20/height)*height;
			addEventListener(Event.ENTER_FRAME, followMouse);
		}

		private function followMouse(e:Event):void
		{
			var xdiff:Number = MovieClip(parent).mouseX - x;
			var ydiff:Number = MovieClip(parent).mouseY - y;
			var dist:Number = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
			if (dist < DISTANCE)
			{
				var angle:Number = Math.atan2(ydiff,xdiff);
				var sp:Number = (speed/dist)*3;
				x = startX - Math.cos(angle) * sp;
				y = startY - Math.sin(angle) * sp;
			}
		}
	}
}

And here’s how it’s been generated:

import pl.bedkowski.code.clownfish.ClowFishBall;

var dist = 10;
for(var ii=0,j=0;ii<9;ii++) {
	for(var i=15,h=1;i<310;i+=dist,j++,h+=.3) {
		var mc:MovieClip =  new ClowFishBall(i, 5+dist*ii, h/2);
		addChild(mc);
	}
}

Example:

LICENSE

As you probably noticed there are few entries in my blog that deal with usage of cglib. There was one thing though that kept me a bit frustrated – why wasn’t it possible to use JDK 1.5 generics when creating eg. new Ehnancer.

So I decided to add generics which could also get me more familiar with this library. My first step was to download source code from sourceforge and import into cglib-jdk15 repository on my github account. Afterwards I found out that AbstractClassGenerator contains inner Source class which uses caching mechanism for generated classes but unfortunately it wasn’t possible to add generic WeakHashMap without altering the code. Luckily this didn’t seem that much complicated – I just split cache into two separate caches – one for classes and one for References.

After everything was in place I could update Junit Tests and my code snippets blog entries with no more explicit casts.

Than I had a look at ant build script- in order to put generics version into the repository I wanted to use maven’s classifier but to achieve this a build script needed some more attention. It looked like its task could be replaced with maven tasks/conventions. It all worked – I could even generate „nodep” package but in this case I think that project structure still needs some attention.

Finally in order to build the project you can issue following command:

mvn clean install javadoc:javadoc jxr:jxr jxr:jxr-test site

As usual modfied source code available on github.

Binaries in my repository.

Problem description

Imagine you have a project with hierarchical data structure with 4 levels, where 1st level serves as reference data for 2nd and so on. So your task as a developer is to present this on a web form with a checkbox for each value, where „checked” means that it has its own value and „unchecked” means that value of such a field should be taken from it’s parent, with exception for 1st level, which should use only its own values. Furthermore the DTO used for form should pass its state into remote EJB.

Requirements

So let’s summarize it as requirements:

I want to be able to bind a command object with pair of fields – one used for remote EJB and one for determining if field is available on this level. In case field is not available remote EJB object should be passed a null value.

Solution discussion

Simple if/else

The easiest solution is to use regular if/else block and in case field is not available set null passed value otherwise, eg:


if (myCommand.isFieldAvailable()) {
   myRemote.setField(myCommand.getField());
} else {
   myRemote.setField(null);
}

It does the job but it’s a bit of an overhead when you have 20 fields – all 100 lines look alike:

  • check if field is available
  • pass its value to ejb
  • set null otherwise

An experienced OOP developer, which I’m sure you are, sees a needless repetition here and it’s obvious that there’s got to be a better way.

Reflection

Another apporach is to use reflection with property names passed as strings and a helper method which retrieves these using reflection and applies them accrodingly, eg:


fromCommandToEJB("field", command, ejb);

Internally this method will encapsulate logic for checking if available flag is set and reacts to it. This version is much better but it still has one flaw – property name is passed as string and compiler will not warn you when any change in the interface takes place.

Delegating proxy

Proxy may sound a bit intimidating but cglib’s Ehnancer makes it very easy – the only requirement is that you can’t use final classes.

So the work-horse of this solution is MethodInterceptor that has 3 tasks:

  1. Intercept call to a method
  2. Determine if call should be handled (method should be a JavaBean getter).
  3. Handle supported method call (find suffixed method and execute it in order to check what value should be returned).

The first point is handled by cglib internally, so we’re not going to spend any more time on it.

Second point is the decission making part – which  is a slightly modified version of isGetter method presented by Jakob Jenkov in his article on reflection. We’re going to intercept both get and is methods but exclude the ones ending with Available suffix and instead of returning a boolean our method returns a String where null means that method should not be handled.

	private String getHandledPropertyName(Method method) {
		String methodName = method.getName();
		if (!(methodName.startsWith("get") ||
			(methodName.startsWith("is") &&
			!methodName.endsWith(suffix)))) {
			return null;
		}
		else if (method.getParameterTypes().length != 0 ||
			void.class == method.getReturnType()) {
			return null;
		}
		else if (methodName.startsWith("get")) {
			return methodName.substring(3);
		} else {
			return methodName.substring(2);
		}
	}

As you can see returned String is important so we can have decission making (get/is prefix) and propoperty name reading (everything following is/get prefix).

There is a small overhead – every property needs to have an isAvailable method, which in case of compound properties means that each call must be redirected to the „real” checker.

Let’s try an example here – your bean contains start/endDate method so endDate is not valid without startDate, which means that there should be a common method checking if both dates are set and only afterwards passing it for further processing but with proxy you need to have isStartDateAvailable and isEndDateAvailable which might make code analysis a bit harder, so remember to use proper comments to make others work easier.

Third point is very simple – for given property name, find correspoint isAvailable method, check its return value and either call original method, passing its return value or return null.

	private Object handleGetter(Method method, String propertyName) throws Throwable {
		String conditionPropertyName = StringUtils.uncapitalize(propertyName) + suffix;
		PropertyDescriptor conditionDescriptor = PropertyUtils.getPropertyDescriptor(myBean, conditionPropertyName);
		if (conditionDescriptor == null) {
			throw new NoSuchMethodException("Missing is"+StringUtils.capitalize(conditionPropertyName) + " method for property: " + StringUtils.uncapitalize(propertyName));
		}
		Method condition = conditionDescriptor.getReadMethod();
		if (condition == null) {
			throw new NoSuchMethodException("Missing is"+StringUtils.capitalize(conditionPropertyName) + " method for property: " + StringUtils.uncapitalize(propertyName));
		}
		if ((Boolean) condition.invoke(myBean)) {
			return method.invoke(myBean);
		}
		return null;
	}

I’ve added also a small utility static method, to make wiring the whole stuff a bit easier.

	public static <T> T create(T myBean, String suffix) {
		return (T) Enhancer.create(myBean.getClass(), new ConditionalPropertyInterceptor<T>(myBean, suffix));
	}

There’s just one last thing that needs attention – how to make sure that each getter has a corresponding isAvailable method. Yes you can take your chances and wait until application is deployed… but it’s much better to have so me kind of automatic testing – in this case I recommend using dozer library exclude transient properties and after excluding transient properties all the rest should pass.

Sources available on github

Problem description

Let’s say that your multi-tiered application consists of numerous components:

  • webservice server
  • webservice client
  • business component-logic
  • front-end web application

These components communicate with each-other through SOAP webservices and from time to time your customer is reporting an error which you know is caused by non-compatible changes done in the webservice call – which baiscally means that he did not do a full upgrade – one of the components is at least one version behind.

The project is built using maven and each release has its own version so the idea is to put this version into easily-accessible form so that each time this problem rises developers could ask customer for the version of a component and thus make sure that problem rised is not upgrade issue.

Requirements

So lets first specify requirements for this task:

I want to have version of each component easily accessible for users. Version should be applied automatically . After a release it should not be possible to alter version without recompiling the code.

Solution discussion

Version should be easily accessible

The first requirement is a little bit vauge easily accessible mitght differ from person to person but it’s also stated that person accessing it might have little or nothing to do with development or programming at all, that’s why solution with writing version of component into the log file might not be enough.

Probably the easiest solution is just to point user to a certain URL within application server, let him take screenshot of version and treat it as PREREQUISITE of all bug reports.

All application servers have managed beans and in JBoss there’s also a jmx-console where mbeans can be accessed with their properties and in case sombody still prefers command line – there’s a utility script called twiddle that can access mbeans from command-line. In order for this to work there needs to be mbean configured within JBoss application server.

Version should be applied automatically

Since project is built with maven this requirement is achieved easily – we just need to add resource filtering, apply version number within the resource and make it accessible to the mbean.

It should not be possible to alter version without recompiling the code

This requirement makes it a bit more compliated – using the previous one only, it could have been just a text file added to the jar and than loaded using Property class. Right now the only option is to have somehow java class treated as a resource, this means that first there should be resource filtering applied and java class should be placed in src/main/java and than everything would go as normal.

This makes any changes to this class a bit harder since one must know that version class is someplace else than src/main/java but proper comment should do the trick.

Solution description

Requirement analysis presented us with a view of how the solution should look like:

  • It should be a java class
  • This java class should be filtered using maven resource filtering
  • This java class should have version property applied when doing resource filtering
  • This java class should be treated by JBoss application server as mbean
  • mbean should contain a meaningful name so it’s easy to find it in the jmx console

Let’s start with creating a java class for our mbean:


public class MyVersion {

  private String version = "${project.version}";

  public String getVersion() {

    return version;

  }

}

As you can see in the code sample above, version property does have a setter – this is a way to mark it as readonly property in the JMX console.

Now maven needs to know that this class should be treated as regular resource and apply filtering – thus replacing project.version property with current version number.

So first approach would be to change src/man/java into something different but since it’s a strong convention this proved to be hard (if not impossible).

So another approach is to use special directory called src/main/tpl and add it as additional resource directory whose output should be placed into src/main/java.

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.5</version>
        <executions>
          <execution>
            <id>copy-resources</id>
            <!-- here the phase you need -->
            <phase>validate</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>${basedir}/src/main/java</outputDirectory>
              <resources>
                <resource>
                  <directory>src/main/tpl</directory>
                  <filtering>true</filtering>
                  <includes>
                    <include>**/*.java</include>
                  </includes>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
    ...
  </build>
  ...
</project>

The only thing that’s left is to register our mbean so it’s available through JMX console. On JBoss there’s special extension of EJB3 specification called POJO service. It’s specific annotation that informes JBoss AS to create single instance of your class and have it registered in JNDI under specified name.

So let’s see how our code changes after applying it:

@Service(objectName = "projectName.VersionClass")
@Management(MyVersion.class)
public class MyVersionImpl implements MyVersion {

 private String version = "${project.version}";

 public String getVersion() {

 return version;

 }

}

As you can see in the code above – there are two annotations @Service and @Management. The latter requires a management interface to be specified so let’s create one:


public interface MyVersion {

String getVersion();

}

And that’s it – now we can always tell our client to first provide us with screenshot of a version before handling any bug reports.

NOTE:  In case you were wondering if it’s possible to add service mbean into existing jar in your project be warned that the author of this post has tried that and JBoss AS tried to register the same mbean twice – first when loading the jar alone and second time when loading the jar as a dependency of embedded war which as you can guess resulted in Exception thrown.

UPDATE: See updated version of this solution – using ejb 3.1 only, compilant with any application server here.

package pl.bedkowski.code.userType.EnumSetUserType;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

public class EnumSetUserType<E extends Enum<E>> implements UserType {
	private Class<? extends EnumSet> clazz = null;
	private Class<E> typeClazz = null;
	protected EnumSetUserType(Class<E> c) {
		this.clazz = EnumSet.noneOf(c).getClass();
		typeClazz = c;
	}

	private static final int[] SQL_TYPES = {Types.VARCHAR};
	public int[] sqlTypes() {
		return SQL_TYPES;
	}

	public Class returnedClass() {
		return clazz;
	}

	public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
		String name = resultSet.getString(names[0]);
		EnumSet<E> result = null;
		if (!resultSet.wasNull()) {
			String[] values = name.split(",");
			List<E> enumList = new ArrayList<E>();
			for(String value : values) {
				enumList.add(Enum.valueOf(typeClazz, value));
			}
			result = EnumSet.copyOf(enumList);
		}
		return result;
	}

	public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException {
		if (null == value) {
			preparedStatement.setNull(index, Types.VARCHAR);
		} else {
			Set<E> values = (Set<E>)value;
			String sqlValue = "";
			if (!values.isEmpty()) {
				StringBuffer buf = new StringBuffer();
				for(E val : values) {
					buf.append(val.name()).append(",");
				}
				sqlValue = buf.substring(0, buf.length() - 1);
			}
			preparedStatement.setString(index, sqlValue);
		}
	}

	public Object deepCopy(Object value) throws HibernateException{
		return value;
	}

	public boolean isMutable() {
		return false;
	}

	public Object assemble(Serializable cached, Object owner) throws HibernateException {
		return cached;
	}

	public Serializable disassemble(Object value) throws HibernateException {
		return (Serializable)value;
	}

	public Object replace(Object original, Object target, Object owner) throws HibernateException {
		return original;
	}
	public int hashCode(Object x) throws HibernateException {
		return x.hashCode();
	}
	public boolean equals(Object x, Object y) throws HibernateException {
		if (x == y)
			return true;
		if (null == x || null == y)
			return false;
		return x.equals(y);
	}
}

Usage

public class User {
    public enum TYPE{admin,guest};
}

///

import pl.bedkowski.code.userType.EnumSetUserType;

public class UserType extends EnumSetUserType<User.TYPE> {
	public UserType() {
		super(User.TYPE.class);
	}
}

Problem description

Another approach to the memoization topic mentioned previously came to me quite recently based on a problem with webservice call.

Imagine you have a webservice request/response exchange that’s taking a long time not only due to network latency but also due to the fact that your ws-logic performs a complicated ldap query.

So there are at least 3 reasons that might cause you a headache:

  1. slow internet connection
  2. slow ldap search
  3. big number of results that need to downloaded

In order to improve this situation results of method call might be cached inside ws-client’s code using ehacache. Cached entries will be identified based on method’s signature and passed arguments. The arguments should implement Serializable interface but this is already fulfilled since objects are passed through webservice calls.

Caching should be transparent to the caller – which should not know whether results he got were fetched from remote server or local cache. Additionally it should be configurable which methods calls should be cached or not and last but not least – since cached entries are identified by some key – it should be possible to define custom key-generator that would give the user freedom in defning key algorithm.

All the above requirements are summarized below:

  • webservice client api defined as interface
  • webservice client implementation that performs call to server
  • methods are chosen based on annotations
  • wraper defined as dynamic proxy so calls to client api are transparently may be cached and user is not aware if results come from cache or real call

Solution description

The solution will be spring-specific since Spring supports ehacache out-of-the-box.

Existing solutions

There exists already at least 3 solutions:

and somehow all of them combined fill the picture of what I’d expect from such a library:

Requirements
  1. Easy configuration with possibly as little xml as possible – smth like <context:component-scan> element with reasonable defaults
  2. Defining one annotation that enables method caching
  3. Including/Excluding methods from caching using annotation
Solution description

The approach descried in this post is realised by providing 3 main elements:

  1. Custom namespace handler implementing NamespaceHandlerSupport
  2. Custom bean definition parser extending AbstractSingleBeanDefinitionParser
  3. Custom BeanPostProcessor implmenting BeanFactoryAware interface
  4. Custom xsd

All points above respond to the requrements:

Points 1 and 2 let you declare usage of method cache with just one line of xml (after defining memoize namesapace) and creates EhCacheManagerFactoryBean and EhCacheFactoryBean behind-the-scenes freeing you from writing these explicitly inside you xml application context.

<memoize:use-method-cache
   config-location="classpath:ehcache.xml"
   cache-name="pl.bedkowski.code.memoize.sample.METHOD_CACHE" />

Point 3 finds classes annotated with Memoize annotation inside current context and wraps them inside Memoizer proxy, as well as fetches EhCacheFactoryBean instance created in the previous step.

@Component("wsClient")
@Memoize
public class WebServiceClientImpl implements WebServiceClient {

The Memoize annotation contains 2 properties:

  • keyGenerator – key generator class (must implement KeyGeneratorinterface)
  • type – one of Type.INCLUDE_ALL/Type.EXCLUDE_ALL

I think the last one needs some further explanation – it lets you define strategy for handling methods.

  • Default is Type.INCLUDE_ALL – which means that all methods that have non-void return type will be cached unless explicitly marked with Exclude annotation.
  • The reverse is Type.EXCLUDE_ALL which means that no method call will be cached unless marked with Includeannotation.

Sources, packages

Source available on github
Binaries available in repo

UPDATE: See updated version using ejb 3.1 compilant with any application server here.