Beispiel #1
0
  private ValueType typeOf(final Object value, final FieldBinding binding) throws BindException {
    if (value == null) {
      return ValueType.NIL;
    }

    final Class<?> cls = value.getClass();
    ValueType type = typeCache.get(cls);
    if (type == null) {
      if (binding != null && recipesByClass.containsKey(binding.getFieldType())) {
        final Mapping<?> recipe = recipesByClass.get(binding.getFieldType());

        if (recipe instanceof ArrayMapping) {
          type = ValueType.ARRAY;
        } else if (recipe instanceof StructMapping) {
          type = ValueType.STRUCT;
        } else {
          throw new BindException(
              "Unknown recipe reference type: "
                  + binding.getFieldType()
                  + "\nField: "
                  + binding.getFieldName()
                  + "\nClass: "
                  + cls.getName());
        }
      } else {
        type = ValueType.typeFor(value);
      }

      if (type != null) {
        typeCache.put(cls, type);
      }
    }

    return type;
  }
Beispiel #2
0
  private Field findField(final FieldBinding binding, final Class<?> parentCls)
      throws BindException {
    Field field = null;
    Class<?> fieldOwner = parentCls;
    while (field == null && fieldOwner != null) {
      try {
        field = fieldOwner.getDeclaredField(binding.getFieldName());
      } catch (final NoSuchFieldException e) {
        // TODO: log this to debug log-level.
        field = null;
        fieldOwner = fieldOwner.getSuperclass();
      }
    }

    if (field == null) {
      throw new BindException(
          "Cannot find field: "
              + binding.getFieldName()
              + " in class (or parent classes of): "
              + parentCls.getName());
    }

    return field;
  }
Beispiel #3
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);
    }
  }