XStream
  1. XStream
  2. XSTR-341

Unmarshalling of implicit arrays

    Details

    • Type: New Feature New Feature
    • Status: Closed Closed
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.4
    • Component/s: None
    • Labels:
      None

      Description

      The implicit unmarshalling support should be expanded beyond collections to include java array types. The use of array binding has the advantage infering the type of the element when it is not provided by the type attribute in the message. It's a common binding for XSD based services.

      This is not an easy case to extend because it involves overriding of ReflectionConverer, which has a lot of additional responsiblities. However, I was able to make it work with relatively easy changes. I've included changes I made to ReflectionConverter below as snippets.

      ....
      private class ArrayElem {
      public List list;
      public Class type;
      ArrayElem(List list, Class type)

      { this.list = list; this.type = type; }

      }

      ...

      Map implciitArrays = null;

      // ... add as additional condition before fieldClass.isAssiableFrom(...) ....

      if (fieldClass.isArray()) {
      Class elementClass = fieldClass.getComponentType();

      // optional type may be present for polymorphic types:
      String typeName = reader.getAttribute(mapper.attributeForImplementationClass());
      if (typeName != null)

      { elementClass = mapper.realClass(typeName); if (elementClass == null) throw new RuntimeException("realClass returned null for " + typeName); }

      Object value = context.convertAnother(result, elementClass);
      if (implciitArrays == null) implciitArrays = new HashMap(); // lazy instantiation

      ArrayElem elem = (ArrayElem) implciitArrays.get(fieldName);
      if (elem == null)

      { elem = new ArrayElem(new ArrayList(), elementClass); implciitArrays.put(fieldName, elem); }

      elem.list.add(value);
      } else....

      ///.... At end of unmarshall method....

      // write implict arrays after all values are read

      if (implciitArrays != null) {
      for (Iterator iter = implciitArrays.entrySet().iterator(); iter.hasNext()

      { Map.Entry e = (Map.Entry) iter.next(); String fieldName = (String) e.getKey(); ArrayElem elem = (ArrayElem) e.getValue(); List list = elem.list; Object array = Array.newInstance(elem.type, list.size()); reflectionProvider.writeField( result, fieldName, list.toArray((Object[]) array),null); }

      }

        People

        • Assignee:
          Jörg Schaible
          Reporter:
          Erik Smith
        • Votes:
          1 Vote for this issue
          Watchers:
          0 Start watching this issue

          Dates

          • Created:
            Updated:
            Resolved: