Code generation would be the only other way I can think of. Personally, I'd got with a generally reusable reflection solution (unless that part of the code is absolutely performance-critical). Using JMS sounds like overkill (additional dependency, and that's not even what it's meant for). Besides, it probably uses reflection as well under the hood.
JSON, for example using XStream + Jettison, is a simple text format with key value pairs. It is supported for example by the Apache ActiveMQ JMS message broker for Java object exchange with other platforms / languages.
and take advantage of JodaProperties. This does stipulate that you create beans in a particular way however, and implement a specific interface. It does then however, allow you to return a property map from a specific class, without reflection. Sample code is here:
If you do not want to hardcode calls to each getter and setter, reflection is the only way to call these methods (but it is not hard).
Can you refactor the class in question to use a Properties object to hold the actual data, and let each getter and setter just call get/set on it? Then you have a structure well suited for what you want to do. There is even methods to save and load them in the key-value form.
You can basically convert any compatible types: compatible meaning that if you did convert from type to JSON, and from that JSON to result type, entries would match (if configured properly can also just ignore unrecognized ones).
Works well for cases one would expect, including Maps, Lists, arrays, primitives, bean-like POJOs.
If it comes to a simple object tree to key value list mapping, where key might be a dotted path description from the object's root element to the leaf being inspected, it's rather obvious that a tree conversion to a key-value list is comparable to an object to xml mapping. Each element within an XML document has a defined position and can be converted into a path. Therefore I took XStream as a basic and stable conversion tool and replaced the hierarchical driver and writer parts with an own implementation. XStream also comes with a basic path tracking mechanism which - being combined with the other two - strictly leads to a solution being suitable for the task.
If you really really want performance you can go the code generation route.
You can do this on your on by doing your own reflection and building a mixin AspectJ ITD.
Or you can use Spring Roo and make a Spring Roo Addon. Your Roo addon will do something similar to the above but will be available to everyone who uses Spring Roo and you don't have to use Runtime Annotations.
I have done both. People crap on Spring Roo but it really is the most comprehensive code generation for Java.
The BeanWrapper offers functionality to set and get property values (individually
or in bulk), get property descriptors, and to query properties to determine if they
are readable or writable.
Company c = new Company();
BeanWrapper bwComp = BeanWrapperImpl(c);
bwComp.setPropertyValue("name", "your Company");
public static Map<String, Object> getBeanMap(Object bean) {
Map<String, Object> beanMap = new HashMap<String, Object>();
BeanWrapper beanWrapper = new BeanWrapper(BeanWrapperContext.create(bean.getClass()));
for(String propertyName : beanWrapper.getPropertyNames())
beanMap.put(propertyName, beanWrapper.getValue(propertyName));
return beanMap;
}
I developed Juffrou myself. It's open source, so you are free to use it and modify. And if you have any questions regarding it, I'll be more than happy to respond.
There is of course the absolute simplest means of conversion possible - no conversion at all!
instead of using private variables defined in the class, make the class contain only a HashMap which stores the values for the instance.
Then your getters and setters return and set values into and out of the HashMap, and when it is time to convert it to a map, voila! - it is already a map.
With a little bit of AOP wizardry, you could even maintain the inflexibility inherent in a bean by allowing you to still use getters and setters specific to each values name, without having to actually write the individual getters and setters.
Essentially, it traverses the entire object graph reachable from the object given as input, and produces a map from all primitive type/String fields on the objects. It can be configured to output either:
a flat map: {rootObject.someField=Joe, rootObject.leafObject.someField=Jane}, or
a structured map: {someField=Joe, leafObject={someField=Jane}}.
Here's an example from their page:
public class Parent{
private Child child;
private String name;
// setters and getters are omitted
}
public class Child{
private String name;
private List<String> nickNames;
// setters and getters are omitted
}
With the help of Jackson library, I was able to find all class properties of type String/integer/double, and respective values in a Map class. (without using reflections api!)
Probably late to the party. You can use Jackson and convert it into a Properties object. This is suited for Nested classes and if you want the key in the for a.b.c=value.