I'm trying to read values from a collection of objects (Tag) and map them to a jaxb generated object using reflection. I've a field list which filters the required fields from the main object.
Here's the sample code. I'm using the inner class Tag as the list from where values need to be extracted. The List fieldList acts as the filter. The goal is to copy those values to a jaxb generated object using reflection. I'm using javabean PropertyDescriptor to achieve this.
Now, I'm stuck with the problem of setting values for collection fields in the jaxb object. For List fields, jaxb doesn't provide a setter, rather you've to use a getList().add(object). How do I acheive this ?
public class ReflectionTest2 {
/**
* @param args
*/
public static void main(String[] args) {
try{
ReflectionTest2 testObj = new ReflectionTest2();
List<Tag> tagList = new ArrayList<Tag>();
createTag(tagList, testObj);
List<String> fieldList = new ArrayList<String>();
fieldList.add("ADSKContentGroup");
fieldList.add("title");
CaasContextObject object = new CaasContextObject();
for(Tag each : tagList){
innerLoop:
for(String field : fieldList){
if(each.name.equals(field)){
for (PropertyDescriptor pd : Introspector.getBeanInfo(
CaasContextObject.class).getPropertyDescriptors()) {
if(pd.getWriteMethod() != null && !"class".equals(pd.getName())){
if(pd.getName().equals(each.name)){
if(pd.getPropertyType().isAssignableFrom(java.util.List.class)){
// handle list
}else{
pd.getWriteMethod().invoke(object, each.value);
}
break innerLoop;
}
}
}
}
}
}
// Read object
System.out.println("\n\nPrinting Title -->"+object.getTitle());
for(String cg : object.getADSKContentGroup()){
System.out.println(cg);
}
}catch (Exception e) {
e.printStackTrace();
}
}
private static void createTag(List<Tag> tagList, ReflectionTest2 obj){
Tag tag1 = obj.new Tag();
tag1.setName("ADSKContentGroup");
tag1.setValue("Documentation");
tagList.add(tag1);
Tag tag2 = obj.new Tag();
tag2.setName("ADSKContentGroup");
tag2.setValue("User Guide");
tagList.add(tag2);
Tag tag3 = obj.new Tag();
tag3.setName("title");
tag3.setValue("Test Title");
tagList.add(tag3);
}
public class Tag {
protected String name;
protected String value;
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
Jaxb generated object
public class CaasContextObject{
@XmlElement(required = true)
protected String title;
@XmlElement(name = "ADSKContentGroup")
protected List<String> adskContentGroup;
public String getTitle() {
return title;
}
public void setTitle(String value) {
this.title = value;
}
/**
* Gets the value of the adskContentGroup property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the adskContentGroup property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getADSKContentGroup().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link String }
*
*
*/
public List<String> getADSKContentGroup() {
if (adskContentGroup == null) {
adskContentGroup = new ArrayList<String>();
}
return this.adskContentGroup;
}
}
As you can see, the issue is with setting the adskContentGroup value.
Any pointers will be appreciated.
Thanks
Is this what you're looking for?
if (pd.getReadMethod() != null && pd.getReadMethod().getReturnType().isAssignableFrom(List.class)) {
Method method = pd.getReadMethod();
List list = (List) method.invoke(mc);
list.add("Hello World!"); // change the passed String of course
}