diff --git a/wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/EntityConfig.java b/wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/EntityConfig.java index 63b2c75..ebd3ab7 100644 --- a/wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/EntityConfig.java +++ b/wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/EntityConfig.java @@ -9,6 +9,7 @@ import org.cobbzilla.util.string.HasLocale; import org.cobbzilla.util.string.StringUtil; import org.cobbzilla.wizard.model.entityconfig.annotations.*; import org.cobbzilla.wizard.model.search.SqlViewField; +import org.cobbzilla.wizard.validation.HasValue; import org.cobbzilla.wizard.validation.ValidationResult; import org.cobbzilla.wizard.validation.Validator; import org.springframework.core.type.filter.AnnotationTypeFilter; @@ -530,7 +531,7 @@ public class EntityConfig { ECForeignKey fkAnnotation, Map fieldIndexes) { final EntityFieldConfig cfg = new EntityFieldConfig() - .setRequired(fieldAnnotation.required()) + .setRequired(fieldIsRequired(accessor, fieldAnnotation)) .setMode(fieldAnnotation.mode()) .setType(getFieldType(fieldName, fieldAnnotation, accessor, fkAnnotation)); if (!empty(fieldAnnotation.name())) cfg.setName(fieldAnnotation.name()); @@ -547,6 +548,21 @@ public class EntityConfig { return cfg; } + private boolean fieldIsRequired(AccessibleObject accessor, ECField fieldAnnotation) { + if (fieldAnnotation.required() != EntityFieldRequired.unset) { + return fieldAnnotation.required().bool(); + } + HasValue hasValueAnnotation = accessor.getAnnotation(HasValue.class); + if (hasValueAnnotation != null) return true; + Column columnAnnotation = accessor.getAnnotation(Column.class); + if (columnAnnotation == null) return true; + if (columnAnnotation.nullable()) return false; + if (!empty(columnAnnotation.columnDefinition()) && columnAnnotation.columnDefinition().matches("\\s+NOT\\s+NULL\\s*")) { + return true; + } + return false; + } + private EntityFieldType getFieldType(String fieldName, ECField fieldAnnotation, AccessibleObject accessor, ECForeignKey fkAnnotation) { if (fieldAnnotation.type() != EntityFieldType.none_set) return fieldAnnotation.type(); if (fkAnnotation != null) return EntityFieldType.reference; diff --git a/wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/annotations/ECField.java b/wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/annotations/ECField.java index 7dde23b..fe3ccf3 100644 --- a/wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/annotations/ECField.java +++ b/wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/annotations/ECField.java @@ -18,7 +18,7 @@ public @interface ECField { String displayName() default ""; EntityFieldMode mode() default EntityFieldMode.standard; EntityFieldType type() default EntityFieldType.none_set; - boolean required() default true; + EntityFieldRequired required() default EntityFieldRequired.unset; int length() default -1; EntityFieldControl control() default EntityFieldControl.unset; String options() default ""; diff --git a/wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/annotations/EntityFieldRequired.java b/wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/annotations/EntityFieldRequired.java new file mode 100644 index 0000000..e945a1c --- /dev/null +++ b/wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/annotations/EntityFieldRequired.java @@ -0,0 +1,17 @@ +package org.cobbzilla.wizard.model.entityconfig.annotations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public enum EntityFieldRequired { + + required (true), optional (false), unset (null); + + private final Boolean booleanValue; + + @JsonCreator public static EntityFieldRequired fromString (String v) { return valueOf(v.toLowerCase()); } + + public Boolean bool() { return booleanValue; } + +}