[ https://issues.apache.org/jira/browse/TUSCANY-1833?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12535931 ]
Jiang Chen commented on TUSCANY-1833: ------------------------------------- Thanks. That was the problem. I assumed arrays are wrapped in a parent component. Below is the XML I used: <property element="ns0:personElement" many="false" name="person" noDefault="false"> <ns0:null> <ns0:firstname/> <ns0:middlename/> <ns0:lastname/> <ns0:hobbies> <ns0:hobby> <ns0:name>asdf</ns0:name> </ns0:hobby> <ns0:hobby> <ns0:name>asdf</ns0:name> </ns0:hobby> </ns0:hobbies> </ns0:null> </property> Representing arrays as a sequence of elements without a parent element certainly works. A bit of a catch is that I can't name the Java bean property "hobbies" but rather "hobby" to match with the XML element name, while the property is a plural. > XML2JavaBeanTransformer has problem transforming to beans with array fields > --------------------------------------------------------------------------- > > Key: TUSCANY-1833 > URL: https://issues.apache.org/jira/browse/TUSCANY-1833 > Project: Tuscany > Issue Type: Bug > Components: Java SCA Data Binding Runtime > Affects Versions: Java-SCA-1.0 > Reporter: Jiang Chen > Fix For: Java-SCA-Next > > > I tried to use complex properties in a POJO which requires the SCA runtime at > injection time to convert complex XML property values into Java beans. The > XML2JavaBeanTransformer in the java beans data binding package seems to have > problem converting to beans with array members. Mapping exception was thrown. > In both the setFieldValue and the setFieldValueUsingSetter methods of > org.apache.tuscany.sca.databinding.javabeans.XML2JavaBeanTransformer, when > the field type is Array, it probably should convert all the child elements of > the field value to Java objects and add them to the field value array. The > current implementation tries to convert the field value itself (the parent of > the array elements) yet using the component type of the array. > The following fix seems to have fixed my problem. > private void setFieldValue(Object javaInstance, > Field javaField, > T fieldValue, > Map<Field, List<Object>> arrayFields, > TransformationContext context) throws > IllegalAccessException { > Class<?> javaFieldType = (Class<?>) javaField.getType(); > if (javaFieldType.isArray()) { > Class<?> componentType = javaFieldType.getComponentType(); > List<Object> fldValueArray = arrayFields.get(javaField); > if (fldValueArray == null) { > fldValueArray = new ArrayList<Object>(); > arrayFields.put(javaField, fldValueArray); > } > > /*********************** Fix Starts *************************/ > // Old code commented out: > // fldValueArray.add(createJavaObject(fieldValue, componentType, > context)); > > // New code added: > List<T> childElements = getChildElements(fieldValue); > > for (int i = 0; i < childElements.size(); i++) > if (!isTextElement(childElements.get(i))) > fldValueArray.add(createJavaObject(childElements.get(i), componentType, > context)); > /*********************** Fix Ends *************************/ > } else { > javaField.setAccessible(true); > javaField.set(javaInstance, createJavaObject(fieldValue, > javaFieldType, context)); > } > } > private void setFieldValueUsingSetter(Class javaType, > Object javaInstance, > String fieldName, > T fieldValue, > Map<Method, List<Object>> > arraySetters, > TransformationContext context) > throws IllegalAccessException, > > InvocationTargetException { > char firstChar = Character.toUpperCase(fieldName.charAt(0)); > StringBuilder methodName = new StringBuilder(SET + fieldName); > methodName.setCharAt(SET.length(), firstChar); > boolean methodNotFound = true; > for (int methodCount = 0; methodNotFound && methodCount < > javaType.getMethods().length; ++methodCount) { > Method aMethod = javaType.getMethods()[methodCount]; > if (aMethod.getName().equals(methodName.toString()) > && aMethod.getParameterTypes().length == 1) { > Class<?> paramType = aMethod.getParameterTypes()[0]; > if (paramType.isArray()) { > Class<?> componentType = paramType.getComponentType(); > List<Object> setterValueArray = arraySetters.get(aMethod); > if (setterValueArray == null) { > setterValueArray = new ArrayList<Object>(); > arraySetters.put(aMethod, setterValueArray); > } > > /*********************** Fix Starts > *************************/ > // Old code commented out: > // setterValueArray.add(createJavaObject(fieldValue, > componentType, context)); > > // New code added: > List<T> childElements = getChildElements(fieldValue); > > for (int i = 0; i < childElements.size(); i++) > if (!isTextElement(childElements.get(i))) > setterValueArray.add(createJavaObject(childElements.get(i), componentType, > context)); > /*********************** Fix Ends > *************************/ > } else { > aMethod.invoke(javaInstance, new Object[] > {createJavaObject(fieldValue, > > paramType, > > context)}); > } > methodNotFound = false; > } > } > if (methodNotFound) { > XML2JavaMapperException xml2JavaEx = > new XML2JavaMapperException("No field or setter method to > configure xml data"); > xml2JavaEx.setJavaFieldName(fieldName); > xml2JavaEx.setJavaType(javaType); > throw xml2JavaEx; > } > } -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]