Пример #1
0
  /**
   * 验证字段值
   *
   * @param bean
   * @return
   */
  private static final <T> ConstraintViolation<T> validateFieldContext(T bean, FieldContext fc) {
    if (fc == null) {
      return null;
    }

    ConstraintViolation<T> violation = null;

    Object fieldValue = getFieldValue(bean, fc.getFieldMethod());

    // 首先验证其是否是Required
    Annotation requiredConstraint = fc.getRequiredConstraint();
    if (requiredConstraint != null) {
      violation = validateField(bean, fc.getField(), fieldValue, requiredConstraint);
      if (violation != null) {
        return violation;
      }
    }

    // 验证其它规则
    for (Annotation otherConstraint : fc.getConstraints()) {
      // 不再处理Required
      if (otherConstraint.annotationType() == Required.class) {
        continue;
      }

      violation = validateField(bean, fc.getField(), fieldValue, otherConstraint);
      if (violation != null) {
        return violation;
      }
    }

    return null;
  }
Пример #2
0
  /**
   * 验证JavaBean
   *
   * @param bean 需要验证的JavaBean对象
   * @param fields 需要可能指定验证的Bean字段
   * @return 验证结果
   */
  @SuppressWarnings("unchecked")
  public static final <T> ConstraintViolation<T>[] validate(T bean, String... fields) {
    if (bean == null) {
      throw new ValidationException("Validated JavaBean object can not be null!");
    }

    if (bean.getClass() == Object.class) {
      return new ConstraintViolation[0];
    }

    FieldContext[] fieldContexts =
        ValidationContextCache.getConstraintFieldContexts(bean.getClass());
    if (fieldContexts == null || fieldContexts.length == 0) {
      return new ConstraintViolation[0];
    }

    // 对指定的field进行提取
    FieldContext[] needFieldContexts = null;
    if (fields != null && fields.length > 0) {
      needFieldContexts = new FieldContext[fields.length];
      int i = 0;
      boolean fExist = false; // 检测指定的field是否存在于给定的Bean中

      for (String f : fields) {
        if (f == null || f.trim().length() == 0) {
          continue;
        }

        fExist = false;
        for (FieldContext fc : fieldContexts) {
          if (fc.getField().getName().equals(f)) {
            needFieldContexts[i++] = fc;
            fExist = true;
            break;
          }
        }

        if (!fExist) {
          throw new ValidationException(
              "The field `"
                  + f
                  + "` is not exists in constraint fields of `"
                  + bean.getClass().getName()
                  + "`!");
        }
      }

      // 指定的field都为null或空,则指定无效,验证全部
      if (i == 0) {
        needFieldContexts = fieldContexts;
      }
    } else {
      needFieldContexts = fieldContexts;
    }

    List<ConstraintViolation<T>> violations =
        new ArrayList<ConstraintViolation<T>>(needFieldContexts.length);
    ConstraintViolation<T> fcv = null;

    for (FieldContext fc : needFieldContexts) {
      fcv = validateFieldContext(bean, fc);

      if (fcv != null) {
        violations.add(fcv);
      }
    }

    return violations.toArray(new ConstraintViolation[violations.size()]);
  }
  public Query createQuery(FieldContext fieldContext) {
    final Query perFieldQuery;
    final String fieldName = fieldContext.getField();

    /*
     * Store terms per position and detect if for a given position more than one term is present
     */
    TokenStream stream = null;
    boolean isMultiPhrase = false;
    Map<Integer, List<Term>> termsPerPosition = new HashMap<Integer, List<Term>>();
    final String sentence = phraseContext.getSentence();
    try {
      Reader reader = new StringReader(sentence);
      stream = queryContext.getQueryAnalyzer().tokenStream(fieldName, reader);

      CharTermAttribute termAttribute = stream.addAttribute(CharTermAttribute.class);
      PositionIncrementAttribute positionAttribute =
          stream.addAttribute(PositionIncrementAttribute.class);

      stream.reset();
      int position = -1; // start at -1 since we apply at least one increment
      List<Term> termsAtSamePosition = null;
      while (stream.incrementToken()) {
        int positionIncrement = 1;
        if (positionAttribute != null) {
          positionIncrement = positionAttribute.getPositionIncrement();
        }

        if (positionIncrement > 0) {
          position += positionIncrement;
          termsAtSamePosition = termsPerPosition.get(position);
        }

        if (termsAtSamePosition == null) {
          termsAtSamePosition = new ArrayList<Term>();
          termsPerPosition.put(position, termsAtSamePosition);
        }

        String termString = new String(termAttribute.buffer(), 0, termAttribute.length());
        termsAtSamePosition.add(new Term(fieldName, termString));
        if (termsAtSamePosition.size() > 1) {
          isMultiPhrase = true;
        }
      }
    } catch (IOException e) {
      throw new AssertionFailure("IOException while reading a string. Doh!", e);
    } finally {
      if (stream != null) {
        try {
          stream.end();
          stream.close();
        } catch (IOException e) {
          throw new AssertionFailure("IOException while reading a string. Doh!", e);
        }
      }
    }

    /*
     * Create the appropriate query depending on the conditions
     * note that a MultiPhraseQuery is needed if several terms share the same position
     * as it will do a OR and not a AND like PhraseQuery
     */
    final int size = termsPerPosition.size();
    if (size == 0) {
      perFieldQuery = new BooleanQuery.Builder().build();
    } else if (size <= 1) {
      final List<Term> terms = termsPerPosition.values().iterator().next();
      if (terms.size() == 1) {
        perFieldQuery = new TermQuery(terms.get(0));
      } else {
        BooleanQuery.Builder booleanQueryBuilder = new BooleanQuery.Builder();
        for (Term term : terms) {
          booleanQueryBuilder.add(new TermQuery(term), BooleanClause.Occur.SHOULD);
        }
        perFieldQuery = booleanQueryBuilder.build();
      }
    } else {
      if (isMultiPhrase) {
        MultiPhraseQuery query = new MultiPhraseQuery();
        query.setSlop(phraseContext.getSlop());
        for (Map.Entry<Integer, List<Term>> entry : termsPerPosition.entrySet()) {
          final List<Term> value = entry.getValue();
          query.add(value.toArray(new Term[value.size()]), entry.getKey());
        }
        perFieldQuery = query;
      } else {
        PhraseQuery query = new PhraseQuery();
        query.setSlop(phraseContext.getSlop());
        for (Map.Entry<Integer, List<Term>> entry : termsPerPosition.entrySet()) {
          final List<Term> value = entry.getValue();
          query.add(value.get(0), entry.getKey());
        }
        perFieldQuery = query;
      }
    }
    return fieldContext.getFieldCustomizer().setWrappedQuery(perFieldQuery).createQuery();
  }