private boolean propertyStartsWithFieldMarkerPrefix(PropertyValue pv, String fieldMarkerPrefix) { String propertyName = pv.getName().indexOf(PATH_SEPARATOR) > -1 ? StringUtils.substringAfterLast(pv.getName(), ".") : pv.getName(); return propertyName.startsWith(fieldMarkerPrefix); }
@SuppressWarnings("unchecked") private void bindCollectionAssociation(MutablePropertyValues mpvs, PropertyValue pv) { Object v = pv.getValue(); Collection collection = (Collection) bean.getPropertyValue(pv.getName()); collection.clear(); final Class associatedType = getReferencedTypeForCollection(pv.getName(), getTarget()); final boolean isArray = v != null && v.getClass().isArray(); final PropertyEditor propertyEditor = findCustomEditor(collection.getClass(), pv.getName()); if (propertyEditor == null) { if (isDomainAssociation(associatedType)) { if (isArray) { Object[] identifiers = (Object[]) v; for (Object id : identifiers) { if (id != null) { associateObjectForId(pv, id, associatedType); } } mpvs.removePropertyValue(pv); } else if (v != null && (v instanceof String)) { associateObjectForId(pv, v, associatedType); mpvs.removePropertyValue(pv); } } else if (GrailsDomainConfigurationUtil.isBasicType(associatedType)) { if (isArray) { Object[] values = (Object[]) v; List list = collection instanceof List ? (List) collection : null; for (int i = 0; i < values.length; i++) { Object value = values[i]; try { Object newValue = getTypeConverter().convertIfNecessary(value, associatedType); if (list != null) { if (i > list.size() - 1) { list.add(i, newValue); } else { list.set(i, newValue); } } else { collection.add(newValue); } } catch (TypeMismatchException e) { // ignore } } } } } }
private String getNameOf(PropertyValue propertyValue) { String name = propertyValue.getName(); if (name.indexOf(STRUCTURED_PROPERTY_SEPERATOR) == -1) { return name; } return name.substring(0, name.indexOf(STRUCTURED_PROPERTY_SEPERATOR)); }
/** * Check the given property values against the required fields, generating missing field errors * where appropriate. * * @param mpvs the property values to be bound (can be modified) * @see #getRequiredFields * @see #getBindingErrorProcessor * @see BindingErrorProcessor#processMissingFieldError */ protected void checkRequiredFields(MutablePropertyValues mpvs) { String[] requiredFields = getRequiredFields(); if (!ObjectUtils.isEmpty(requiredFields)) { Map<String, PropertyValue> propertyValues = new HashMap<String, PropertyValue>(); PropertyValue[] pvs = mpvs.getPropertyValues(); for (PropertyValue pv : pvs) { String canonicalName = PropertyAccessorUtils.canonicalPropertyName(pv.getName()); propertyValues.put(canonicalName, pv); } for (String field : requiredFields) { PropertyValue pv = propertyValues.get(field); boolean empty = (pv == null || pv.getValue() == null); if (!empty) { if (pv.getValue() instanceof String) { empty = !StringUtils.hasText((String) pv.getValue()); } else if (pv.getValue() instanceof String[]) { String[] values = (String[]) pv.getValue(); empty = (values.length == 0 || !StringUtils.hasText(values[0])); } } if (empty) { // Use bind error processor to create FieldError. getBindingErrorProcessor().processMissingFieldError(field, getInternalBindingResult()); // Remove property from property values to bind: // It has already caused a field error with a rejected value. if (pv != null) { mpvs.removePropertyValue(pv); propertyValues.remove(field); } } } } }
private void registerBeanDefinitionsWithRegistry(BeanDefinitionRegistry registry) { for (Object key : beanDefinitions.keySet()) { BeanDefinition bd = beanDefinitions.get(key); if (LOG.isDebugEnabled()) { LOG.debug("[RuntimeConfiguration] Registering bean [" + key + "]"); if (LOG.isTraceEnabled()) { PropertyValue[] pvs = bd.getPropertyValues().getPropertyValues(); for (PropertyValue pv : pvs) { LOG.trace( "[RuntimeConfiguration] With property [" + pv.getName() + "] set to [" + pv.getValue() + "]"); } } } final String beanName = key.toString(); if (registry.containsBeanDefinition(beanName)) { removeBeanDefinition(registry, beanName); } registry.registerBeanDefinition(beanName, bd); registerBeanAliases(registry, beanName); } }
private void registerBeanConfigsWithRegistry(BeanDefinitionRegistry registry) { for (BeanConfiguration bc : beanConfigs.values()) { String beanName = bc.getName(); if (LOG.isDebugEnabled()) { LOG.debug("[RuntimeConfiguration] Registering bean [" + beanName + "]"); if (LOG.isTraceEnabled()) { PropertyValue[] pvs = bc.getBeanDefinition().getPropertyValues().getPropertyValues(); for (PropertyValue pv : pvs) { LOG.trace( "[RuntimeConfiguration] With property [" + pv.getName() + "] set to [" + pv.getValue() + "]"); } } } if (registry.containsBeanDefinition(beanName)) { removeBeanDefinition(registry, beanName); } registry.registerBeanDefinition(beanName, bc.getBeanDefinition()); registerBeanAliases(registry, beanName); } }
private PropertyValues filterPropertyValues(PropertyValues propertyValues, String prefix) { if (prefix == null || prefix.length() == 0) return propertyValues; PropertyValue[] valueArray = propertyValues.getPropertyValues(); MutablePropertyValues newValues = new MutablePropertyValues(); for (PropertyValue propertyValue : valueArray) { String name = propertyValue.getName(); final String prefixWithDot = prefix + PREFIX_SEPERATOR; if (name.startsWith(prefixWithDot)) { name = name.substring(prefixWithDot.length(), name.length()); newValues.addPropertyValue(name, propertyValue.getValue()); } } return newValues; }
/** * Check the given property values against the allowed fields, removing values for fields that are * not allowed. * * @param mpvs the property values to be bound (can be modified) * @see #getAllowedFields * @see #isAllowed(String) */ protected void checkAllowedFields(MutablePropertyValues mpvs) { PropertyValue[] pvs = mpvs.getPropertyValues(); for (PropertyValue pv : pvs) { String field = PropertyAccessorUtils.canonicalPropertyName(pv.getName()); if (!isAllowed(field)) { mpvs.removePropertyValue(pv); getBindingResult().recordSuppressedField(field); if (logger.isDebugEnabled()) { logger.debug( "Field [" + field + "] has been removed from PropertyValues " + "and will not be bound, because it has not been found in the list of allowed fields"); } } } }
@SuppressWarnings("unchecked") private ConstrainedProperty getConstrainedPropertyForPropertyValue( Map constrainedProperties, PropertyValue propertyValue) { final String propertyName = propertyValue.getName(); if (propertyName.indexOf(PATH_SEPARATOR) > -1) { String[] propertyNames = propertyName.split("\\."); Object target = getTarget(); Object value = getPropertyValueForPath(target, propertyNames); if (value != null) { Map nestedConstrainedProperties = resolveConstrainedProperties(value); if (nestedConstrainedProperties != null) { return (ConstrainedProperty) nestedConstrainedProperties.get(propertyNames[propertyNames.length - 1]); } } } else { return (ConstrainedProperty) constrainedProperties.get(propertyName); } return null; }
/** * Auto-creates the a type if it is null and is possible to auto-create. * * @param mpvs A MutablePropertyValues instance */ protected void autoCreateIfPossible(MutablePropertyValues mpvs) { PropertyValue[] pvs = mpvs.getPropertyValues(); for (PropertyValue pv : pvs) { String propertyName = pv.getName(); if (propertyName.indexOf(PATH_SEPARATOR) > -1) { String[] propertyNames = propertyName.split("\\."); BeanWrapper currentBean = bean; for (String name : propertyNames) { Object created = autoCreatePropertyIfPossible(currentBean, name, pv.getValue()); if (created != null) { currentBean = new BeanWrapperImpl(created); } else { break; } } } else { autoCreatePropertyIfPossible(bean, propertyName, pv.getValue()); } } }
/** * This overrides the method from WebDataBinder to allow for nested checkbox handling, so property * paths such as a._b will result in the boolean b on object a getting set to false. */ @Override protected void checkFieldMarkers(MutablePropertyValues mpvs) { if (getFieldMarkerPrefix() == null) { return; } String fieldMarkerPrefix = getFieldMarkerPrefix(); PropertyValue[] pvArray = mpvs.getPropertyValues(); for (PropertyValue pv : pvArray) { // start of variation from superclass method if (propertyStartsWithFieldMarkerPrefix(pv, fieldMarkerPrefix)) { String field = stripFieldMarkerPrefix(pv.getName(), fieldMarkerPrefix); // end of variation from superclass method if (getPropertyAccessor().isWritableProperty(field) && !mpvs.contains(field)) { Class<?> fieldType = getPropertyAccessor().getPropertyType(field); mpvs.add(field, getEmptyValue(field, fieldType)); } mpvs.removePropertyValue(pv); } } }
/** * Interrogates the specified properties looking for properites that represent associations to * other classes (e.g., 'author.id'). If such a property is found, this method attempts to load * the specified instance of the association (by ID) and set it on the target object. * * @param mpvs the <code>MutablePropertyValues</code> object holding the parameters from the * request */ protected void bindAssociations(MutablePropertyValues mpvs) { for (PropertyValue pv : mpvs.getPropertyValues()) { String propertyName = pv.getName(); String propertyNameToCheck = propertyName; final int i = propertyName.indexOf('.'); if (i > -1) { propertyNameToCheck = propertyName.substring(0, i); } if (!isAllowed(propertyNameToCheck)) continue; if (propertyName.endsWith(IDENTIFIER_SUFFIX)) { propertyName = propertyName.substring(0, propertyName.length() - 3); if (!isAllowed(propertyName)) continue; if (isReadableAndPersistent(propertyName) && bean.isWritableProperty(propertyName)) { if (NULL_ASSOCIATION.equals(pv.getValue())) { bean.setPropertyValue(propertyName, null); mpvs.removePropertyValue(pv); } else { Class<?> type = getPropertyTypeForPath(propertyName); Object persisted = getPersistentInstance(type, pv.getValue()); if (persisted != null) { bean.setPropertyValue(propertyName, persisted); } } } } else { if (isReadableAndPersistent(propertyName)) { Class<?> type = getPropertyTypeForPath(propertyName); if (Collection.class.isAssignableFrom(type)) { bindCollectionAssociation(mpvs, pv); } } } } }
private boolean isStructured(PropertyValue propertyValue) { String name = propertyValue.getName(); return name.indexOf(STRUCTURED_PROPERTY_SEPERATOR) != -1; }
private void associateObjectForId(PropertyValue pv, Object id, Class<?> associatedType) { final Object target = getTarget(); final Object obj = getPersistentInstance(associatedType, id); addAssociationToTarget(pv.getName(), target, obj); }