Archive

Archive for the ‘java’ Category

Serializing CGLIB enhanced proxy into JSON using XStream

June 25th, 2010 admin No comments

I use a custom very lightweight persistence library that does lazy loading using CGLIB Enhanced proxy.
THe generated proxy for domain objects use Key/value Map data fed to it via a static factory method.
When a get or set method is called for the wrapped domain, the proxy check the value for the field in the Map,
if it finds an entry for the field, which means the field hasn’t been initialised, it sets the field value from Map and removes
the entry from the Map.
If no entry is found in the Map, the method returns value of the field of the domain object encapsulated by the getter method
rather than getting it from the Map.

Of course if the field is a domain object, then the object is fetched using the PK value in the Map.
That gives me the same lazy loading voodoo magic like Hibernate- the 10 pound gorrila.
The persistence is backed by a cache which looks at a domain’s metadata and
only caches those that are specified as cacheable.

Everything works like a charm except that the CGLIB enhanced objects don’t play nice with XStream at all.
When serializing enhanced objects XStream spits out gory details of classe/superclasses/interfaces and full dissection of a Map that is fed to a static method when creating the proxy object, when all i want is the pojo object wrapped by the proxy.

I believe the XStream library simply gets the value of the field rather than calling the getter method using reflection when serializing.
That must be the reason that in my case all serialised objects have empty values for fields because the fields don’t get set when the proxy is
created, they get set only setter method is called on it or getter method is called for the first time .
I think that’s the same problem with Hibernate and I guess that’s the reason it throws Lazy Initilization Exception.

I tried the CGLIBEnhancedConverter that comes with the library but it didn’t work for me.
I couldn’t find a simple enough solution in the internet and the ones I found were all Hibernate specific.
Since this is the second time I had been trying to solve the issue, I decided to push forward and find a work around myself.

After trying out a few different solutions I finally came up with a dead simple solution.
IT involves a static method to deproxy the enhanced domain objects and a XStream custom converter class.
There may be performance cost as it uses reflection eventhough getter setter methods for domain classes are cached for reuse.

Here’s the simplified method.


  /**
     * Deproxies a CGLIB enhanced proxy object
     * @param <T>
     * @param proxy
     * @return deproxied domain object
     */
    public static <T > T deproxyReflection(final T proxy) {

      Class entityClass = proxy.getClass().getSuperclass();

        T entity = (T) ClassUtil.getInstance(entityClass);

        Field[] fields =  entityClass.getDeclaredFields();

        for (Field f : fields) {
            try {

	 // no need to set the values of collections as they won;t be serialized.
                //we just need the actaul properties taht amp to table columns
                if(List.class.isAssignableFrom(f.getType()))
                    continue;

                //I use a utility method to fetch getter/setter methods.
                //it simply loops through the object and super class to find the methods.
//so instead of screwing arund with the field's security settings we'll use getters/setters to ensure its unintrusive
                Method getter = ClassUtil.getPojoMethod(entityClass, f.getName(), ClassUtil.MethodType.GETTER);
                Method setter = ClassUtil.getPojoMethod(entityClass, f.getName(), new Class[]{f.getType()}, ClassUtil.MethodType.SETTER);

                Object val = getter.invoke(proxy, null);
                setter.invoke(entity, new Object[]{val});

            } catch (Exception ex) {
                Logger.getLogger(EntityProxyFactory.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                f.set(entity, f.get(proxy));
            } catch (Exception ex) {
                Logger.getLogger(EntityProxyFactory.class.getName()).log(Level.SEVERE, null, ex);
            } 

        }

        return entity;
    }

We need to register a converter with XStream that used the above method to sanitize the domain objects before serializing.


/**
 * XStream converter to convert a CGLIB enhanced proxy  to the wrapped pojo object.
 *
 */
public class CGLIBEnhancedEntityConverter implements Converter {

    public boolean canConvert(Class clazz) {
        return (Enhancer.isEnhanced(clazz)  || clazz == CGLIBMapper.Marker.class) ;
    }

    public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {

            // deproxy before sending it off the chain for serialization. ANd that's it.
           // XStream will get a simple pojo object and it will serialize it like any other pojo object.
         context.convertAnother(EntityProxyFactory.deproxyReflection(source));

    }

    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {

    throw new Error("not supported");
    }

}

And that’s it. That’s all it takes.
If a domain object has other domain objects as fields, those fields will not be handled by the above method.
For that there are two choices. Firstly you can look at the field’s class type and say if t implements or extends your base Domain class/interface, you can deproxy them recursively.
In my case all domain objects implement a bare minimum interface called IEntity with only one getId() method.

the above method can be modified to recursively deproxy/sanitize a domain’s fields if they are proxied objects.


//.............
            Object val = getter.invoke(proxy, null);

                if (IEntity.class.isAssignableFrom(f.getType()) {
                    val=deproxy(val);//recursively deproxy the fields if they are enhanced objects
                }
                setter.invoke(entity, new Object[]{val});

If you only have to serialize a handful of domain objects, it might be better to register converters
for those fields at startup instead of using the above method.

Say, we have a domain class State with Country as one of its field, we can register the above converter to convert the country object as below.


//.............
//entity manager that handles all persistence needs
IEntityManager em= (IEntityManager) BeanFactory.getBean("entityManager");

//fetch a list of State objects with id smaller than3
       List<State> list= em.fetch(State.class, "id<3");

//uses factory method to instantiate Xstream
xstream xstream= XStreamFactory.getXstream(Format.JSON);

CGLIBEnhancedEntityConverter cglibConverter= new CGLIBEnhancedEntityConverter();

//register default converter
xstream.registerConverter(cglibConverter);

//register field converter. country field for State objects
xstream.registerLocalConverter(State.class, "country", cglibConverter);

//spit out the serialized json objects
 System.out.println(xs.toXML(list));

here’s the result without deproxying the domain object:
The before version :-)


{"list": [
  {
    "code": "",
    "name": "",
    "daylightSavingStart": "",
    "daylightSavingEnd": "",
    "CGLIB$BOUND": true,
    "CGLIB$CALLBACK_0": {
      "@class": "com.barahisolutions.proxy.EntityProxyFactory$EntityMethodInterceptor",
      "data": [
        {},
        {
          "default": {
            "loadFactor": 0.75,
            "threshold": 12
          },
          "int": 16,
          "int": 8,
          "string": "id",
//..................................................
//there's 10 times more of this garbage which i didn;t bother to print out.

And here's the nice and clean pojo version of the deproxied proxy objects.
I used the recursive option to inspect properties if objects and deproxy them if they are proxied domain
objects.
The after version :-)


{"list": [
  {
    "id": 1,
    "code": "NSW",
    "name": "New South Wales",
    "utcOffset": 10.0,
    "daylightSavingOn": false,
    "daylightSavingStart": "",
    "daylightSavingEnd": "",
    "country": {
      "id": 18,
      "code": "",
      "name": "Barbados"
    }
  },
  {
    "id": 2,
    "code": "VIC",
    "name": "Victoria",
    "daylightSavingOn": false,
    "daylightSavingStart": "",
    "daylightSavingEnd": "",
    "country": {
      "id": 12,
      "code": "AUS",
      "name": "Australia"
    }
  }
]}

Grouping Java objects using object’s properties/fields

June 12th, 2010 admin No comments

I recently had to build a HTML select list with items grouped by category .
The list had to be populated using ajax as using simple jsp tag wasn’t enough as I needed other
properties besides simple key/ value and group for validation and displaying description of the selected item using javascript .

Since grouping objects can be quite quite handy for displaying grouped data in forms and in reports I ended up creating a utility method in java which takes a List of objects and a field name to group the objects by ,
and returns a map with keys as the values of the field name and values a a list of objects under this group.

Here’s the method .


    /**
     * Groups objects using field name provided
     *  @param list the list of objects to group
     * @param field the field to group the objects by
     * @return new Map containing list of objects.
     * The Map's key is the property specified in criteria object
     */

public static <V> Map<String,List<V>> group(List<V> list, String field) {

            //used for indexing to avoid too much looping
	     HashMap<String,K> index= new HashMap<String,K>();
      // the container for grouped data. K is the data type for the field's value.
        HashMap<K,List<V>> groupedData= new HashMap<K, List<V>>();

      // the method to invoke to get the value of the 'field' prop from objects
         Method m=null;

        try {
          V obj=list.get(0);
       // Used a handy Util Class's method for getting the getter method for 'field'
          m = ClassUtil.getMethod(obj.getClass(), "get"+StringUtil.getFirstUpper(field));
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(ListUtil.class.getName()).log(Level.SEVERE, null, ex);

            return null;
        }

       //iterate through the list of objects passed as parameter
        for (V object : list) {

	//the 'field' value of object
             K columnVal=null;

             try {
                    columnVal = (K) m.invoke(object, null);

                     // group of objects under columnVal group
                       List<V> group=groupedData.get(index.get(columnVal.toString()));

                if(group==null){
                    group= new ArrayList<V>();
                groupedData.put(columnVal, group);
                index.put(columnVal.toString(), columnVal);
                }
                //add the object to the group
                group.add(object);

                } catch (Exception ex) {
                    Logger.getLogger(ListUtil.class.getName()).log(Level.SEVERE, null, ex);
                }
        }

        return groupedData;

}

here’s a simple test:


   List<Command> commands= new ArrayList();

//create objects to populate a list;

        Command comm= new DeviceCommand();
        comm.setCommand("CONTROL comm1");
        comm.setCommandType(CommandType.CONTROL);
        comm.setName(" CONTROL command 1");
        commands.add(comm);

          Command comm2= new DeviceCommand();
        comm2.setCommand("comm2");
        comm2.setCommandType(CommandType.CONTROL);
        comm2.setName(" CONTROL command 2");
        commands.add(comm2);

          Command comm3= new DeviceCommand();
        comm3.setCommand("INFORMATION comm1");
        comm3.setCommandType(CommandType.INFORMATION);
        comm3.setName("INFORMATION command 1");
        commands.add(comm3);

          Command comm5= new DeviceCommand();
        comm5.setCommand("SETTING comm1");
        comm5.setCommandType(CommandType.SETTING);
        comm5.setName("SETTING command 1");
        commands.add(comm5);

          Command comm6= new DeviceCommand();
        comm6.setCommand("SETTING comm2");
        comm6.setCommandType(CommandType.SETTING);
        comm6.setName("SETTING command 2");
        commands.add(comm6);

           Command comm8= new DeviceCommand();
        comm8.setCommand("OTHER comm1");
        comm8.setCommandType(CommandType.OTHER);
        comm8.setName("OTHER command 1");
        commands.add(comm8);

          Command comm4= new DeviceCommand();
        comm4.setCommand("CONTROL comm4");
        comm4.setCommandType(CommandType.CONTROL);
        comm4.setName("CONTROL  command 4");
        commands.add(comm4);

           Command comm7= new DeviceCommand();
        comm7.setCommand("SETTING comm3");
        comm7.setCommandType(CommandType.SETTING);
        comm7.setName("SETTING command 3");
        commands.add(comm7);

          Command comm9= new DeviceCommand();
        comm9.setCommand("OTHER comm2");
        comm9.setCommandType(CommandType.OTHER);
        comm9.setName("OTHER command 2");
        commands.add(comm9);

          Command comm10= new DeviceCommand();
        comm10.setCommand("OTHER comm3");
        comm10.setCommandType(CommandType.OTHER);
        comm10.setName("OTHER command 3");
        commands.add(comm10);

      //convert  list of Command objects into a map with commandTpe as key and list of Commands within
    // that group as  map value.
        Map<String,List<Command>> grouped=ListUtil.group(commands, "commandType");

	//print out the grouped map data.
        System.out.println(grouped.toString());

And the string representation of the grouped data :

{OTHER=[OTHER command 1, OTHER command 2, OTHER command 3], SETTING=[SETTING command 1, SETTING command 2, SETTING command 3], CONTROL=[ CONTROL command 1,  CONTROL command 2, CONTROL  command 4], INFORMATION=[INFORMATION command 1]}
Categories: Software Development, java Tags:

using java style import to include javascript files

May 23rd, 2009 admin No comments

I had used a function and a little bootstrapping trick to solve my problem with including files in PHP and I was happy with it.
But recently while working on a project that has a heavy javascript codebase, I started having trouble managing  all javascript file imports and all those script tags made pages look really ugly.
And also I really longed for java’s clas importing capabilities in javascript such that I could import a single file based on package name or I could import a whole package.
Since some of the pages I’m working requires over 15 script imports, some third-party libraries and some of our own files.
And importing scripts one by one suffers from latency problems as it increases page load time and can contribute to user annoyances.
So I longed for  java’s style of package and class  import and  decided to try my hand on writing some script to emulate imports based on packages.

I jsut used the  similar principle I used with php, but the problem is importing all files in a package isn’t possible in javascript because  javascript cannot read files form disk let alone iterate through a folder and read file content.
For that there was nothing I could do except use some server-side help.

here’s the js file code with  function for importing js file and js files contained in a package(folder).


//create namespace to aviod any present/ future  variable/object/funciton conflicts

if (typeof Anzaan == "undefined" || !Anzaan) {

Anzaan = {};
}

// array to hold all imported files so as not to import them twice
Anzaan.imports = [];

//server side URL for loading whole package content
Anzaan.packageLoaderURL='/Framework/packageLoader/';

//set the base folder for importing files
Anzaan.importBase='js/';

/**
* import a class using the java naming syntax for a class name.
*@param module the module to import
*@param  config object literal with two properties-
* config.packageLoaderURL - the server url for loading all files in a folder/package as a stream
* config.importBase - the base path for importing files
* use config only if necessary otherwise just modify Anzaan.packageLoaderURL and Anzaan.importBase
* of course you can use a different namespace or just use no namespace
*/
function Import(module, config) { //com.anzaan.framework.*

if(config){
if(config.packageLoaderURL)
Anzaan.packageLoaderURL=config.packageLoaderURL;

if(config.importBase)
Anzaan.importBase=config.importBase;
}

// if this import has already happened, don't bother,
if (Anzaan.imports[module] )
return ;

var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';

var src='';
var folders=module.split(".");
for(var i=0;i<folders.length;i++){

if(folders[i].indexOf('*') < 0)
src+=folders[i]+"/";
}
src=src.substring(0,src.length-1);//remove the last slash

if (module.indexOf('*') < 0) { //if not package import
src=Anzaan.importBase+src+".js";
script.src=src;

} else {
script.src=Anzaan.packageLoaderURL+"?package="+Anzaan.importBase+src;
}

head.appendChild(script);
Anzaan.imports[module] = module;
}

The config parameter is optional. It shouldn’t really be used unless you want to load files from locations other tahn the default location of your application and want to use other URL for loading script files.

Just modify the global variables Anzaan.packageLoaderURL and Anzaan.importBase to set the base path and the serverside URL for loading scripts in folder.
And of course rename Anzaan to something more meaningful for you.

Now on the server side here’s a simple php script that services the script file requests.
It loads contents from js flies that reside in folder specified by ‘package’  variable.

packageLoader.php
————————————————

<?php

$folder=$_GET["package"]; // get the package name

$dir = opendir($folder); //open directory

while (($file = readdir($dir)) !== false) {
if (strrpos($file, '.js')) {

echo file_get_contents($folder.'/'.$file); //printout the content of file

}
}

?>

and here’s a Java Servlet for doing the same thing:

JSPackageLoaderServlet.java

public class JSPackageLoaderServlet extends HttpServlet {

@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {

response.setContentType("text/plain");
ServletOutputStream out = response.getOutputStream();

String packagePath = request.getParameter("package");

StringBuilder sb = new StringBuilder();

File myDir = new File(getServletContext().getRealPath(packagePath));
if (myDir.exists() && myDir.isDirectory()) {
File[] files = myDir.listFiles();
for (int y = 0; y < files.length; y++) {

String line = "";
BufferedReader in = new BufferedReader(new FileReader(files[y]));

while ((line = in.readLine()) != null) {
sb.append(line);

}

}

}
out.print(sb.toString());
}
}

Here’s the usage:

Import('anzaan.event.EvenHandler');

Functional Style Programming in Java -List Transformation

May 20th, 2009 admin No comments

I have been reading a lot of posts on functional style programming and its amazing how things can be simplified  by using functional style of programming.
I find it hard to get my head around a lot of the functional programming concepts like Monad and Functors.

I seem to understand what they are when I read articles on them but I keep forgetting  in a few days time and I have to start over again. Perhaps the problem is that I haven’t been able to find use cases for them in my everyday programming which happens to be Java mostly and javascript and PHP occasionally.

Javascript is actually great for functional style programming as Functions are first-class citizens in Javascript.

But recently I actually managed to apply a little functional style programming to solve a recurring task in a java application I’m working on.

I need to transform  full-blown objects into combo-box friendly objects that  I can transform into JSON object and send it to webpages for use in forms.

Let’s take an example of a Person object. The drop-down box for person should have person’s id as value and
for display text  it should be a combination of surname and name.

For ease of use  for getting display text let’s   say we have  a Person class that  returns  name and surname combination  through its toString() method.

So, here’s our person class.

class Person {

private Integer id;
private String name;
private String surname;

// other interesting properties
..........

// getters and setter methods
........
.....
public String toString(){
return surname+", "+name;
}

}

And I have a class called Combovalue.

class Combovalue {

Integer value;
String  label;

public ComboValue(Integer value, String label){
this.value=value;
this.label=label;
}

// getters and setters
.........

}

Now that we necessary classes we need a handy way to map  a List of Person to a List of  comboValues.

For that  we’ll use a Utility class  for mapping and  an interface that has a method to do the transformation .

First is class ListMap which has a static method which takes a list of Type A  objects and returns a List of Type B object.
Well, for our example, the method should take a list of Person and return a List of ComboValue.

And we need an interface that has a method that takes an argument of type A and returns an object of type B.
Of course for our example it should take a person and return a ComboValue.

Here’s the interface that should be implemented to do the object transformation. Its not really transformation per se, but let’s call it that for simplicity.

It takes a parameter of type A and return a value of type B.

public interface ITransformer<A,B> {

public  B transform(A value);

}

Here’s the class whose static method  transforms  a list of type A to list of type B.

public  class ListMap {

public  static <A, B  > List<B>  map(  List<A> list, ITransformer<A,B> f ){

List<B> values= new ArrayList<B>();

for( int i=0; i<list.size();i++){

values.add( f.transform(list.get(i)) );

}
return values;
}

}

Now the usage:
Say we have a method in one of our classes in our application that handles this transformation.
It retrives a list of Person from database, passes it to the map() method of ListMap  serialize it into JSON and returns it.

Class JSONService{

XStream xstream ;

public JSONService(){
xstream = new XStream(new JettisonMappedXmlDriver());

}

public String getPersonCombos(){

//Assume we have a DAO class to retrieve data for us as List.

List<Person> list= pesonDao.getList();

//now the magic
List<ComboValue> combos = ListMap.map(list, new ITransformer<Person, ComboValue>() {

public ComboValue transform(Person person) {

return new ComboValue(person.getId(), person.toString());

}
});

//use XStream to serialize the list into JSON data.
return xstream.toXML(combos)

}

}

That’s alll the magic.

Transforming object by object can be a pain in the back-side. And the above technique is hardly that useful.
As we’ll end up creating methods for each domain to return combo data. And if we have say over 50 domain objects its a pain. And the above abstraction doesn’t ease our pain much

So, Say we define an interface  called Entity that has a single method.

public interface Entity {

public Integer getId();

}

Our person class and all our Domain classes implement this interface.

and our Person class becomes:


class Person implements Entity {

// the rest is unchanged
}

now lets modify our JSONService class.

Class JSONService{

XStream xstream ;

public JSONService(){
xstream = new XStream(new JettisonMappedXmlDriver());

}

public String getCombo( Class clazz){

//Assume we have a DAO factory with a method that returns a DAO object for a given class  to retrieve data for us as List.

List<clazz> list= DAOFactory.get(clazz).getList();

//Since all our domain classes implement Entity interface we pass in the argument type as Entity

List<ComboValue> combos = ListMap.map(list, new ITransformer<Entity, ComboValue>() {

public ComboValue transform(Entity entity) {

return new ComboValue(entity.getId(),  entity.toString());

}
});

//use XStream to serialize the list into JSON data.
return xstream.toXML(combos)

}

}

And now we have a nice way of transforming any entity into ComboValue object and returning it as JSON !

With Java Generics and a bit of inspiration from functional programming we have a reusable classes  that forms a component that will always obey the fundamental rule of  returning List of type B for any supplied list of type A.

Hardly rocket science, but useful piece of abstraction nevertheless.

Categories: Uncategorized, java Tags: