Пример #1
0
  private Object fireValueEvents(
      final FieldBinding binding,
      final Object parent,
      final XmlRpcListener listener,
      EventCallback before,
      EventCallback after)
      throws XmlRpcException {
    final Class<?> parentCls = parent.getClass();
    try {
      final Field field = findField(binding, parentCls);

      field.setAccessible(true);

      Object value = field.get(parent);

      if (isSuppressedNull(field, parentCls, value)) {
        return null;
      }

      final ValueType type = typeOf(value, binding);

      if (before != null) {
        if (!before.call(value, type)) {
          return null;
        }
      }

      Converter converter = field.getAnnotation(Converter.class);
      if (converter == null) {
        Class<?> fieldType = field.getType();
        converter = fieldType.getAnnotation(Converter.class);
      }

      if (converter != null) {
        final ValueBinder vc = XBRBinderInstantiator.newValueUnbinder(converter);
        vc.generate(listener, value, recipesByClass);
      } else if (recipesByClass.containsKey(binding.getFieldType())) {
        if (type == ValueType.ARRAY) {
          value = fireArrayEvents(binding.getFieldType(), value, listener);
        } else if (type == ValueType.STRUCT) {
          value = fireStructEvents(binding.getFieldType(), value, listener);
        } else {
          throw new BindException(
              "Unknown recipe reference type: "
                  + binding.getFieldType()
                  + "\nField: "
                  + binding.getFieldName()
                  + "\nClass: "
                  + parentCls.getName());
        }

        listener.value(value, type);
      } else {
        final Contains contains = field.getAnnotation(Contains.class);
        if (Map.class.isAssignableFrom(binding.getFieldType())) {
          fireMapEvents(value, binding.getFieldName(), contains, listener);
        } else if (binding.getFieldType().isArray()
            || Collection.class.isAssignableFrom(binding.getFieldType())) {
          fireCollectionEvents(value, binding.getFieldName(), contains, listener);
        } else {
          ValueCoercion coercion = type.coercion();
          if (coercion == null) {
            throw new XmlRpcException(
                "Cannot render {} (type: {}) to string. It has no corresponding coercion, and isn't an @ArrayPart or a @StructPart!");
          }
          value = coercion.toString(value);
        }

        listener.value(value, type);
      }

      if (after != null) {
        if (!after.call(value, type)) {
          return null;
        }
      }

      return value;
    } catch (final IllegalAccessException e) {
      throw new BindException(
          "Cannot retrieve field: "
              + binding.getFieldName()
              + " in class: "
              + parentCls.getName()
              + "\nError: "
              + e.getMessage(),
          e);
    }
  }