[
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]