Lima-Loa Version 0.5 User Manual

Chris Nappin, 25/09/2009

 

Contents

Section 1.

What is Lima-Loa?

Section 2.

The Adapter Design Pattern

Section 3.

Supported Platforms

Section 4.

Dependencies

Section 5.

Getting Started

Section 5.1

The Direct API

Section 5.2

Spring Integration

Section 6.

Method Mapping

Section 7.

Parameter and Return Type Mapping

Section 7.1

Built-in Mappings

Section 7.2

Dozer Mappings

Section 8.

Exception Mapping

Appendix A.

License

 

1. What is Lima-Loa?

Lima-Loa is an automated implementation of the Gang of Four Adapter Design Pattern, for Java. It aims to greatly reduce or get rid of the need to write dull boiler plate code when creating an adapter.

Lima-Loa is Open Source software, published under the Apache License, version 2.0.

 

2. The Adapter Design Pattern

The Gang of Four Design Patterns book describes the intent of the Adapter pattern as follows:

Convert the interface of a class into another interface interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

One implementation of the adapter pattern (class adapters) involves multiple inheritance, so is not possible using the Java programming language. Another implementation (object adapters) involves object composition, and is the typical solution when using Java. The following UML diagram shows the participants in the object adapter implementation.

Adapter Design Pattern

The participants are as follows:

In the above diagram, the client calls methodA(int} on the adapter, which then triggers the adapter to call methodB(long) on the target object. The adapter then passes the result of the target method call back to the client. In order to do this, the adapter must convert the int parameter to a long, then the boolean result to a String.

Typically an object adapter would need to be manually written by a developer. In the above simple example that would not be particularly difficult, but in a more complex example where the parameters and results are large graphs of Java objects (e.g. custom JavaBeans) and where exceptions must also be mapped, a reasonably large amount of dull yet brittle code would need to be manually written.

Lima-loa is an automated implementation of an object adapter, and intends to replace large amounts of such dull yet brittle code with a relatively small amount of configuration.

 

3. Supported Platforms

Lima-Loa is a pure Java library, and requires JDK 1.4 or above.

 

4. Dependencies

Lima-Loa requires the below list of libraries. For ease these are included in the "libs" folder of the distribution. Other versions of these libraries may well work, they simply haven't been tested.

 

5. Getting Started

There are two ways to use Lima-Loa, both have exactly the same functionality:

 

5.1 The Direct API

Firstly, create an instance of AdapterFactory by calling one of the following methods on the org.limaloa.AdapterFactory class:

    public static AdapterFactory getInstance()
    
    public static AdapterFactory getInstance(List mappingFiles)

The list of mapping files are for Dozer, more on this later.

These factory instances are relatively expensive objects and are intended to be re-used, for example if you need to create more than one adapter object.

Next, create an adapter object by calling the following method on the factory instance:

    public Object createAdapter(Class sourceInterface, Object target, Map methodMappings)
            throws AdapterCreationException

This returns an object that implements sourceInterface. The target is the object you'd like any adapter method calls to be redirected to, i.e. the object being adapted. The methodMappings is a map of target object method names, keyed by source interface method names. At runtime, all calls to the adapter are seamlessly redirected to the nominated method in the target object.

An exception is thrown if there is anything wrong with the specified configuration. As much as possible is checked at creation time, rather than at runtime.

See the "direct-api/simple" example in the "samples" folder of the distribution for a fully working example. See the ReadMe.txt file in that folder for details of the example.

5.2. Spring Integration

Lima-Loa is a Spring extension, so you simply add it to the classpath and you can use a new schema in your Spring Application Context xml files. Under the covers, the Spring Integration simply calls the Direct API, so the functionality is identical.

Firstly, add the Lima-Loa schema to your Application Context xml file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:ll="http://www.limaloa.org/schema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                        http://www.limaloa.org/schema http://www.limaloa.org/schema/limaloa.xsd">

Then create an Adapter Configuration (this corresponds to an AdapterFactory) as follows:

    <ll:adapterConfiguration/>

Note that unless you need to define some Dozer mapping files then this step is actually optional - if no adapterConfiguration is defined then a default one will be created on demand. Note also that only one adapterConfiguration is allowed per Application Context (this includes any parent xml files in a hierarchical Application Context), if more than one is found then an exception is thrown.

If you would like to specify Dozer mapping files, the syntax is as follows:

    <ll:adapterConfiguration>
        <ll:configFiles>
            <ll:file>custom-bean-mapping1.xml</ll:file>
            <ll:file>custom-bean-mapping2.xml</ll:file>
        </ll:configFiles>
    </ll:adapterConfiguration>

Next, create an adapter as follows:

    <ll:adapter id="source" interface="..source interface.." targetObject="target">
        <ll:methodMapping source="sourceMethod1" target="targetMethod1"/>
        <ll:methodMapping source="sourceMethod2" target="targetMethod2"/>
   </ll:adapter>

This creates an object that implements interface. The targetObject is a reference to a Spring bean you'd like any adapter method calls to be redirected to, i.e. the object being adapted. The methodMappings map source interface method names to target object method names. At runtime, all calls to the adapter are seamlessly redirected to the nominated method in the target object.

The adapter is a bean instance that can be used just as any other Spring bean, for example it can be injected as a property into another object. That other object need not know that Lima-Loa is even being used, as its only dependency is on the source interface.

As with the Direct API, an exception is thrown if there is anything wrong with the specified configuration. As much as possible is checked at creation time, rather than at runtime.

See the "spring/simple" example in the "samples" folder of the distribution for a fully working example. See the ReadMe.txt file in that folder for details of the example.

 

6. Method Mapping

Method mappings are pretty simple in this release, expect this to become more comprehensive in future releases. Only instance methods are supported. Due to referring to methods by names right now, overloaded methods are not supported - if more than one method is found matching a configured source interface or target object method name, then an exception is thrown.

 

7. Parameter and Return Type Mapping

Mapping of "basic" types is handled directly by a built-in mapper, and anything else is delegated to Dozer - which is an Open Source library intended for mapping custom JavaBeans.

 

7.1 Built-in Mappings

The built-in mappings handle the following situations:

Destination
boolean
Boolean
byte
Byte
short
Short
int
Integer
long
Long
float
Float
double
Double
char
Character
String
Source boolean
Boolean
Yes No No No No No No No Yes
byte
Byte
No Yes Yes Yes Yes Yes Yes Yes Yes
short
Short
No Yes*5 Yes Yes Yes Yes Yes Yes Yes
int
Integer
No Yes*5 Yes*5 Yes Yes Yes Yes Yes*5 Yes
long
Long
No Yes*5 Yes*5 Yes*5 Yes Yes Yes Yes*5 Yes
float
Float
No No No No No Yes Yes No Yes
double
Double
No No No No No No Yes No Yes
char
Character
No Yes*5 Yes*3 Yes*3 Yes*3 Yes*3 Yes*3 Yes Yes
String Yes *1 Yes*2 Yes*2 Yes*2 Yes*2 Yes*2 Yes*2 Yes*4 Yes

Any use of unsupported combinations (marked as "No" in the table above) results in a org.limaloa.object.UnsupportedObjectMappingException thrown at runtime.

*1 - Treats "true" (case-insensitive) as true, anything else (including null) as "false", using Boolean.valueOf(String).

*2 - Uses the appropriate Wrapper.valueOf(String) method, which throws java.lang.NumberFormatException if invalid, null or empty.

*3 - Converts the raw 16-bit character value to a number, for example 'A' becomes 65.

*4 - Expects single character length Strings, org.limaloa.object.UnsupportedObjectMappingException thrown at runtime if the String is empty or length is more than 1.

*5 - Checks the numeric value is not too large or too negative to fit into the destination type, org.limaloa.object.InvalidNumericMappingException thrown at runtime if the value cannot fit into the destination type. For example, if converting from a short to byte, the source value must be from -128 to +127.

 

7.2 Dozer Mappings

Dozer (http://dozer.sourceforge.net/) is an object mapper for custom JavaBeans. It expects objects to follow the JavaBean conventions (have a no arguments constructor, and have getter and setter methods for each attribute), and can handle "graphs" of nested and dependent objects of any depth. By default it will map attributes in any source type to attributes in any destination type by attribute name, with any attributes that don't have a matching name in the destination object being left at null. To define attribute mappings when the attribute name differs, or the object graph itself differs, you simply define a Dozer XML mapping file.

When using Dozer within Lima-Loa, XML mapping files are defined in the parameter to the org.limaloa.AdapterFactory getInstance(List mappingFiles) method (if using the Direct API), or are defined by <configFiles> XML elements within the <adapterConfiguration> XML element (if using the Spring Integration).

See the "direct-api/custom-bean" example in the "samples" folder of the distribution for a fully working example of using Dozer with Lima-Loa via the Direct API. See the ReadMe.txt file in that folder for details of the example.

See the "spring/custom-bean" example in the "samples" folder of the distribution for a fully working example of using Dozer with Lima-Loa via Spring Integration. See the ReadMe.txt file in that folder for details of the example.

 

8. Exception Mapping

Mapping of exceptions is not supported in this release. Expect comprehensive exception mapping to be added in future releases. Any checked or unchecked exceptions thrown by a target method call are rethrown by Lima-Loa as java.lang.reflect.InvocationTargetException, with the original exception in the cause.

 

Appendix A. License

Copyright 2009 Chris Nappin

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.