/** * An attribute is valid if declared in an ancestor, and not set in an ancestor. Check if the * value is conforming to its type (string, int, boolean). Internal attribute (associated with a * field) cannot be set. Must be called on the level above. * * <p>Checks if attr is correctly defined for component ent it must be explicitly defined in its * upper groups, for the top group, it must be already existing. * * <p>boolean Forced = true can be set only by Apform. Needed when an internal attribute is set in * the program, Apform propagates the value to the attribute. * * @param attr * @param value * @return */ public PropertyDefinition validDef(String attr, boolean forced) { if (Attribute.isFinalAttribute(attr)) { logger.error("In " + this + ", cannot redefine final attribute \"" + attr + "\""); return null; } if (Attribute.isReservedAttributePrefix(attr)) { logger.error("In " + this + ", attribute\"" + attr + "\" is reserved"); return null; } PropertyDefinition definition = this.getAttrDefinition(attr); if (definition == null) { logger.error("In " + this + ", attribute \"" + attr + "\" is undefined."); return null; } /* * Internal field attributes cannot be set */ if (definition.getInjected() == InjectedPropertyPolicy.INTERNAL && !forced) { logger.error( "In " + this + ", attribute \"" + attr + "\" is an internal field attribute and cannot be set."); return null; } /* * if the same attribute exists above, it is a redefinition. */ ComponentImpl group = (ComponentImpl) this.getGroup(); if (group != null && group.get(attr) != null) { Object groupValue = group.get(attr); String defaultValue = definition.getDefaultValue(); boolean isDefault = defaultValue != null && groupValue.equals( Attribute.checkAttrType(attr, defaultValue, definition.getType())); // If the attribute above is the default value, it is allowed to change it if (!isDefault && !Attribute.isBuiltAttribute(attr)) { logger.error("In " + this + ", cannot redefine attribute \"" + attr + "\""); return null; } } return definition; }