/** * 验证字段值 * * @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; }
/** * 验证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(); }