/** * Learn whether this property is considered mandatory. * @return <code>true</code> if the <code>MANDATORY</code> feature is set to <code>true</code>. * @see {@link Features.Property#MANDATORY} */ public boolean isMandatory() { return getFeature(MANDATORY, Boolean.FALSE).booleanValue(); }
/** * Get javascript validations of this property. * @return String[] * @deprecated */ @Deprecated // remove this method? public String[] getJavaScriptValidations() { return getFeature(JAVASCRIPT_VALIDATION_FUNCTIONS); }
protected void computeRelationships(MetaBean beanInfo, Map<String, MetaBean> cached) { for (MetaProperty prop : beanInfo.getProperties()) { String beanRef = (String) prop.getFeature(REF_BEAN_ID); if (beanRef != null) { prop.setMetaBean(cached.get(beanRef)); } } }
private PropertyDescriptor getPropertyDescriptor(MetaProperty prop) { PropertyDescriptorImpl edesc = prop.getFeature(Jsr303Features.Property.PropertyDescriptor); if (edesc == null) { edesc = new PropertyDescriptorImpl(prop); prop.putFeature(Jsr303Features.Property.PropertyDescriptor, edesc); } return edesc; }
/** * Compute all known relationships for <code>beanInfo</code>. must be called * AFTER cache.cache() to avoid endless loop * * @param beanInfo * - the bean for which to compute relationships */ protected void computeRelationships(MetaBean beanInfo) { for (final MetaProperty prop : beanInfo.getProperties()) { final String beanRef = prop.getFeature(REF_BEAN_ID); computeRelatedMetaBean(prop, beanRef); } }
/** * Compute a single related {@link MetaBean}. * * @param prop meta property * @param beanRef bean reference */ protected void computeRelatedMetaBean(MetaProperty prop, String beanRef) { Class<?> beanType = prop.getFeature(REF_BEAN_TYPE); if (beanType == null) { if (prop.getFeature(REF_CASCADE) != null) { // dynamic type resolution: prop.setMetaBean(new DynamicMetaBean(this)); } } else { prop.setMetaBean(findForClass(beanType)); } }
/** * {@inheritDoc} * * @return the property descriptors having at least a constraint defined */ public Set<PropertyDescriptor> getConstrainedProperties() { Set<PropertyDescriptor> validatedProperties = new HashSet<PropertyDescriptor>(); for (MetaProperty prop : metaBean.getProperties()) { if (prop.getValidations().length > 0 || (prop.getMetaBean() != null || prop.getFeature(Features.Property.REF_CASCADE) != null)) { validatedProperties.add(getPropertyDescriptor(prop)); } } return Collections.unmodifiableSet(validatedProperties); }
protected <T extends ValidationListener> void validateRegExp(ValidationContext<T> context) { final MetaProperty meta = context.getMetaProperty(); final String regExp = (String) meta.getFeature(REG_EXP); if (regExp == null) return; if (context.getPropertyValue() == null) return; final String value = String.valueOf(context.getPropertyValue()); try { Pattern pattern = (Pattern) meta.getFeature(REG_EXP_PATTERN); if (pattern == null) { pattern = Pattern.compile(regExp); meta.putFeature(REG_EXP_PATTERN, pattern); } if (!pattern.matcher(value).matches()) { context.getListener().addError(REG_EXP, context); } } catch (PatternSyntaxException e) { throw new IllegalArgumentException("regular expression malformed. regexp " + regExp + " at " + context, e); } }
/** * Return the property level constraints for a given propertyName or {@code null} if * either the property does not exist or has no constraint. The returned * object (and associated objects including ConstraintDescriptors) are * immutable. * * @param propertyName * property evaluated */ public PropertyDescriptor getConstraintsForProperty(String propertyName) { if (propertyName == null || propertyName.trim().length() == 0) { throw new IllegalArgumentException("propertyName cannot be null or empty"); } MetaProperty prop = metaBean.getProperty(propertyName); if (prop == null) return null; // If no constraints and not cascaded, return null if (prop.getValidations().length == 0 && prop.getFeature(Features.Property.REF_CASCADE) == null) { return null; } return getPropertyDescriptor(prop); }
/** * Add the specified {@link AccessStrategy} to <code>prop</code>; noop if * <code>prop == null</code>. * * @param prop * @param access * @return whether anything took place. */ public boolean addAccessStrategy(MetaProperty prop, AccessStrategy access) { if (prop == null) { return false; } AccessStrategy[] strategies = prop.getFeature(Features.Property.REF_CASCADE); if (strategies == null) { strategies = new AccessStrategy[] { access }; prop.putFeature(Features.Property.REF_CASCADE, strategies); } else if (!ArrayUtils.contains(strategies, access)) { prop.putFeature(Features.Property.REF_CASCADE, ArrayUtils.add(strategies, access)); } return true; }
protected <T extends ValidationListener> void validateTimeLag(ValidationContext<T> context) { String lag = (String) context.getMetaProperty().getFeature(TIME_LAG); if (lag == null) return; if (context.getPropertyValue() == null) return; long date = ((Date) context.getPropertyValue()).getTime(); long now = System.currentTimeMillis(); if (XMLMetaValue.TIMELAG_Future.equals(lag)) { if (date < now) { context.getListener().addError(TIME_LAG, context); } } else if (XMLMetaValue.TIMELAG_Past.equals(lag)) { if (date > now) { context.getListener().addError(TIME_LAG, context); } } else { throw new IllegalArgumentException("unknown timelag " + lag + " at " + context); } }
protected <T extends ValidationListener> void validateMinLength(ValidationContext<T> context) { Integer maxLength = (Integer) context.getMetaProperty().getFeature(Features.Property.MIN_LENGTH); if (maxLength == null) return; if (context.getPropertyValue() == null) return; final Object value = context.getPropertyValue(); int length = 0; if (value instanceof String) { length = ((String) value).length(); } else if (value instanceof Collection<?>) { length = ((Collection<?>) value).size(); } if (length < maxLength) { context.getListener().addError(MIN_LENGTH, context); } }
protected <T extends ValidationListener> void validateMaxLength(ValidationContext<T> context) { Integer maxLength = (Integer) context.getMetaProperty().getFeature(Features.Property.MAX_LENGTH); if (maxLength == null) return; if (context.getPropertyValue() == null) return; final Object value = context.getPropertyValue(); int length = 0; if (value instanceof String) { length = ((String) value).length(); } else if (value instanceof Collection<?>) { length = ((Collection<?>) value).size(); } if (length > maxLength) { context.getListener().addError(MAX_LENGTH, context); } }
/** * Returns true if the bean involves validation: * <ul> * <li>a constraint is hosted on the bean itself</li> * <li>a constraint is hosted on one of the bean properties, OR</li> * <li>a bean property is marked for cascade (<code>@Valid</code>)</li> * </ul> * * @return true if the bean involves validation */ public boolean isBeanConstrained() { if (hasAnyConstraints()) return true; for (MetaProperty mprop : metaBean.getProperties()) { if (mprop.getMetaBean() != null || mprop.getFeature(Features.Property.REF_CASCADE) != null) return true; } return false; }
protected <T extends ValidationListener> void validateMaxValue(ValidationContext<T> context) { @SuppressWarnings("unchecked") Comparable<Object> maxValue = (Comparable<Object>) context.getMetaProperty().getFeature(MAX_VALUE); if (maxValue == null || context.getPropertyValue() == null) return; if (compare(context, maxValue, context.getPropertyValue()) < 0) { context.getListener().addError(MAX_VALUE, context); } }
protected <T extends ValidationListener> void validateMinValue(ValidationContext<T> context) { @SuppressWarnings("unchecked") Comparable<Object> minValue = (Comparable<Object>) context.getMetaProperty().getFeature(MIN_VALUE); if (minValue == null || context.getPropertyValue() == null) return; if (compare(context, minValue, context.getPropertyValue()) > 0) { context.getListener().addError(MIN_VALUE, context); } }
/** * Create a new PropertyDescriptorImpl instance. * * @param property */ PropertyDescriptorImpl(MetaProperty property) { super(property.getParentMetaBean(), property.getTypeClass(), property.getValidations()); setCascaded(property.getMetaBean() != null || property.getFeature(Features.Property.REF_CASCADE) != null); setPropertyPath(property.getName()); }
/** * Checks if the the meta property <code>prop</code> defines a cascaded bean, and in case it does, validates it. * * @param context The current validation context. * @param prop The property to cascade from (in case it is possible). */ private void validateCascadedBean(GroupValidationContext<?> context, MetaProperty prop) { AccessStrategy[] access = prop.getFeature(Features.Property.REF_CASCADE); if (access != null) { // different accesses to relation // save old values from context final Object bean = context.getBean(); final MetaBean mbean = context.getMetaBean(); // TODO implement Validation.groups support on related bean // Class[] groups = prop.getFeature(Jsr303Features.Property.REF_GROUPS); for (AccessStrategy each : access) { if (isCascadable(context, prop, each)) { // modify context state for relationship-target bean context.moveDown(prop, each); // Now, if the related bean is an instance of Map/Array/etc, ValidationHelper .validateContext(context, new Jsr303ValidationCallback(context), treatMapsLikeBeans); // restore old values in context context.moveUp(bean, mbean); } } } }
AccessStrategy[] access = prop.getFeature(Features.Property.REF_CASCADE); if (access == null && prop.getMetaBean() != null) { // single property access strategy