예제 #1
0
 @Override
 protected boolean isSupported(final Class<?> c, final MappedField optionalExtraInfo) {
   if (optionalExtraInfo != null) {
     return optionalExtraInfo.isMap();
   } else {
     return ReflectionUtils.implementsInterface(c, Map.class);
   }
 }
예제 #2
0
  /** Validate the path, and value type, returning the mapped field for the field at the path */
  static MappedField validateQuery(
      final Class clazz,
      final Mapper mapper,
      final StringBuilder origProp,
      final FilterOperator op,
      final Object val,
      final boolean validateNames,
      final boolean validateTypes) {
    // TODO: cache validations (in static?).

    MappedField mf = null;
    final String prop = origProp.toString();
    boolean hasTranslations = false;

    if (validateNames) {
      final String[] parts = prop.split("\\.");
      if (clazz == null) {
        return null;
      }

      MappedClass mc = mapper.getMappedClass(clazz);
      // CHECKSTYLE:OFF
      for (int i = 0; ; ) {
        // CHECKSTYLE:ON
        final String part = parts[i];
        boolean fieldIsArrayOperator = part.equals("$");

        mf = mc.getMappedField(part);

        // translate from java field name to stored field name
        if (mf == null && !fieldIsArrayOperator) {
          mf = mc.getMappedFieldByJavaField(part);
          if (mf == null) {
            throw new ValidationException(
                format(
                    "The field '%s' could not be found in '%s' while validating - %s; if "
                        + "you wish to continue please disable validation.",
                    part, clazz.getName(), prop));
          }
          hasTranslations = true;
          parts[i] = mf.getNameToStore();
        }

        i++;
        if (mf != null && mf.isMap()) {
          // skip the map key validation, and move to the next part
          i++;
        }

        if (i >= parts.length) {
          break;
        }

        if (!fieldIsArrayOperator) {
          // catch people trying to search/update into @Reference/@Serialized fields
          if (!canQueryPast(mf)) {
            throw new ValidationException(
                format(
                    "Can not use dot-notation past '%s' could not be found in '%s' while"
                        + " validating - %s",
                    part, clazz.getName(), prop));
          }

          // get the next MappedClass for the next field validation
          mc = mapper.getMappedClass((mf.isSingleValue()) ? mf.getType() : mf.getSubClass());
        }
      }

      // record new property string if there has been a translation to any part
      if (hasTranslations) {
        origProp.setLength(0); // clear existing content
        origProp.append(parts[0]);
        for (int i = 1; i < parts.length; i++) {
          origProp.append('.');
          origProp.append(parts[i]);
        }
      }

      if (validateTypes && mf != null) {
        List<ValidationFailure> typeValidationFailures = new ArrayList<ValidationFailure>();
        boolean compatibleForType =
            isCompatibleForOperator(mc, mf, mf.getType(), op, val, typeValidationFailures);
        List<ValidationFailure> subclassValidationFailures = new ArrayList<ValidationFailure>();
        boolean compatibleForSubclass =
            isCompatibleForOperator(mc, mf, mf.getSubClass(), op, val, subclassValidationFailures);

        if ((mf.isSingleValue() && !compatibleForType)
            || mf.isMultipleValues() && !(compatibleForSubclass || compatibleForType)) {

          if (LOG.isWarningEnabled()) {
            LOG.warning(
                format(
                    "The type(s) for the query/update may be inconsistent; using an instance of type '%s' "
                        + "for the field '%s.%s' which is declared as '%s'",
                    val.getClass().getName(),
                    mf.getDeclaringClass().getName(),
                    mf.getJavaFieldName(),
                    mf.getType().getName()));
            typeValidationFailures.addAll(subclassValidationFailures);
            LOG.warning("Validation warnings: \n" + typeValidationFailures);
          }
        }
      }
    }
    return mf;
  }