private ValueType typeOf(final Contains contains) { ValueType vt = null; if (contains != null) { final Mapping<?> recipe = recipesByClass.get(contains.value()); if (recipe != null) { if (recipe instanceof ArrayMapping) { vt = ValueType.ARRAY; } else if (recipe instanceof StructMapping) { vt = ValueType.STRUCT; } else { vt = ValueType.typeFor(contains.value()); } } } return vt; }
@SuppressWarnings("unchecked") private void fireCollectionEvents( final Object values, final String fieldName, final Contains contains, final XmlRpcListener listener) throws XmlRpcException { ValueType vt = typeOf(contains); listener.startArray(); Collection<Object> vals; if (values != null && values.getClass().isArray()) { vals = Arrays.asList((Object[]) values); } else { vals = (Collection<Object>) values; } int i = 0; for (Object entry : vals) { final Class<?> type = entry.getClass(); if (vt == null) { final FieldBinding binding = new FieldBinding(fieldName + "<Map-Value>", type); vt = typeOf(entry, binding); } if (vt == null) { throw new CoercionException( "Cannot find suitable coercion for type: " + (contains == null ? "Un-annotated collection" : contains.value())); } listener.startArrayElement(i); if (ValueType.ARRAY == vt) { fireArrayEvents(type, entry, listener); } else if (ValueType.STRUCT == vt) { fireStructEvents(type, entry, listener); } else { entry = vt.coercion().toString(entry); } listener.value(entry, vt); listener.arrayElement(i, entry, vt); listener.endArrayElement(); i++; } listener.endArray(); }