// Path: src/main/java/net/nextpulse/jadmin/dsl/InputValidationRule.java
// @SuppressWarnings("unused")
// @FunctionalInterface
// public interface InputValidationRule {
//   
//   /**
//    * Validation rule that indicates a required field.
//    */
//   Supplier<InputValidationRule> REQUIRED = () -> (columnDefinition, userInput) -> {
//     if (StringUtils.isBlank(userInput)) {
//       throw new InvalidInputException(String.format("%s is empty but is required", columnDefinition.getName()));
//     }
//   };
//   
//   /**
//    * Validation rule that indicates a minimum length
//    */
//   Function<Integer, InputValidationRule> MINIMUM_LENGTH = (minLength) -> (columnDefinition, userInput) -> {
//     if (StringUtils.isBlank(userInput) || userInput.length() < minLength) {
//       throw new InvalidInputException(String.format("%s is less than %d characters", columnDefinition.getName(), minLength));
//     }
//   };
// 
//   /**
//    * Validation rule that indicates a minimum length or blank
//    */
//   Function<Integer, InputValidationRule> MINIMUM_LENGTH_OR_BLANK = (minLength) -> (columnDefinition, userInput) -> {
//     if (!StringUtils.isBlank(userInput) && userInput.length() < minLength) {
//       throw new InvalidInputException(String.format("%s is less than %d characters", columnDefinition.getName(), minLength));
//     }
//   };
//   
//   /**
//    * Validation rule that indicates a minimum length
//    */
//   Function<Integer, InputValidationRule> MAXIMUM_LENGTH = (maxLength) -> (columnDefinition, userInput) -> {
//     if (userInput.length() > maxLength) {
//       throw new InvalidInputException(String.format("%s is more than %d characters long", columnDefinition.getName(), maxLength));
//     }
//   };
//   
//   /**
//    * Method that will validatePostData (and optionally transform) a user's input value. If the user input is not valid, an
//    * exception is thrown, otherwise the (optionally transformed) user input is returned.
//    *
//    * @param columnDefinition
//    * @param userInput   raw (unsafe!) user data
//    * @throws InvalidInputException  if the user input is invalid
//    */
//   void validate(ColumnDefinition columnDefinition, String userInput) throws InvalidInputException;
// }
// 
// Path: src/main/java/net/nextpulse/jadmin/dsl/InvalidInputException.java
// public class InvalidInputException extends Exception {
//   
//   /**
//    * Creates a new input validation exception with the provided exception message being reported to the user as feedback.
//    *
//    * @param message message to show to the end user
//    */
//   public InvalidInputException(String message) {
//     super(message);
//   }
// }


import net.nextpulse.jadmin.dsl.InputValidationRule;
import net.nextpulse.jadmin.dsl.InvalidInputException;
import spark.utils.StringUtils;
   * @param postEntry        user provided data
   * @param validationMode   validation mode
   * @throws InvalidInputException
   */
  private static void validateColumn(ColumnDefinition columnDefinition, FormPostEntry postEntry, ValidationMode validationMode) throws InvalidInputException {
    if(columnDefinition.isKeyColumn()) {
      // skip the key presence requirement for new entries
      if(validationMode == ValidationMode.EDIT) {
        String input = postEntry.getKeyValues().get(columnDefinition.getName());
        if(StringUtils.isBlank(input)) {
          throw new InvalidInputException("Key column " + columnDefinition.getName() + " is missing");
        }
      }
    } else {
      String input = postEntry.getValues().get(columnDefinition.getName());
      if(!columnDefinition.isEditable()) {
        throw new InvalidInputException("Column " + columnDefinition.getName() + " is not editable");
      }
      
      // validate the actual input
      validateColumn(columnDefinition, input);
    }
  }
  
  /**
   * Validates the user input against the rules configured for the column
   *
   * @throws InvalidInputException if the user data does not pass input validation
   */
  private static void validateColumn(ColumnDefinition columnDefinition, String userData) throws InvalidInputException {
// Path: src/main/java/net/nextpulse/jadmin/dsl/InputValidationRule.java
// @SuppressWarnings("unused")
// @FunctionalInterface
// public interface InputValidationRule {
//   
//   /**
//    * Validation rule that indicates a required field.
//    */
//   Supplier<InputValidationRule> REQUIRED = () -> (columnDefinition, userInput) -> {
//     if (StringUtils.isBlank(userInput)) {
//       throw new InvalidInputException(String.format("%s is empty but is required", columnDefinition.getName()));
//     }
//   };
//   
//   /**
//    * Validation rule that indicates a minimum length
//    */
//   Function<Integer, InputValidationRule> MINIMUM_LENGTH = (minLength) -> (columnDefinition, userInput) -> {
//     if (StringUtils.isBlank(userInput) || userInput.length() < minLength) {
//       throw new InvalidInputException(String.format("%s is less than %d characters", columnDefinition.getName(), minLength));
//     }
//   };
// 
//   /**
//    * Validation rule that indicates a minimum length or blank
//    */
//   Function<Integer, InputValidationRule> MINIMUM_LENGTH_OR_BLANK = (minLength) -> (columnDefinition, userInput) -> {
//     if (!StringUtils.isBlank(userInput) && userInput.length() < minLength) {
//       throw new InvalidInputException(String.format("%s is less than %d characters", columnDefinition.getName(), minLength));
//     }
//   };
//   
//   /**
//    * Validation rule that indicates a minimum length
//    */
//   Function<Integer, InputValidationRule> MAXIMUM_LENGTH = (maxLength) -> (columnDefinition, userInput) -> {
//     if (userInput.length() > maxLength) {
//       throw new InvalidInputException(String.format("%s is more than %d characters long", columnDefinition.getName(), maxLength));
//     }
//   };
//   
//   /**
//    * Method that will validatePostData (and optionally transform) a user's input value. If the user input is not valid, an
//    * exception is thrown, otherwise the (optionally transformed) user input is returned.
//    *
//    * @param columnDefinition
//    * @param userInput   raw (unsafe!) user data
//    * @throws InvalidInputException  if the user input is invalid
//    */
//   void validate(ColumnDefinition columnDefinition, String userInput) throws InvalidInputException;
// }
// 
// Path: src/main/java/net/nextpulse/jadmin/dsl/InvalidInputException.java
// public class InvalidInputException extends Exception {
//   
//   /**
//    * Creates a new input validation exception with the provided exception message being reported to the user as feedback.
//    *
//    * @param message message to show to the end user
//    */
//   public InvalidInputException(String message) {
//     super(message);
//   }
// }


// Path: src/main/java/net/nextpulse/jadmin/InputValidator.java
import net.nextpulse.jadmin.dsl.InputValidationRule;
import net.nextpulse.jadmin.dsl.InvalidInputException;
import spark.utils.StringUtils;

   * @param postEntry        user provided data
   * @param validationMode   validation mode
   * @throws InvalidInputException
   */
  private static void validateColumn(ColumnDefinition columnDefinition, FormPostEntry postEntry, ValidationMode validationMode) throws InvalidInputException {
    if(columnDefinition.isKeyColumn()) {
      // skip the key presence requirement for new entries
      if(validationMode == ValidationMode.EDIT) {
        String input = postEntry.getKeyValues().get(columnDefinition.getName());
        if(StringUtils.isBlank(input)) {
          throw new InvalidInputException("Key column " + columnDefinition.getName() + " is missing");
        }
      }
    } else {
      String input = postEntry.getValues().get(columnDefinition.getName());
      if(!columnDefinition.isEditable()) {
        throw new InvalidInputException("Column " + columnDefinition.getName() + " is not editable");
      }
      
      // validate the actual input
      validateColumn(columnDefinition, input);
    }
  }
  
  /**
   * Validates the user input against the rules configured for the column
   *
   * @throws InvalidInputException if the user data does not pass input validation
   */
  private static void validateColumn(ColumnDefinition columnDefinition, String userData) throws InvalidInputException {
    for(InputValidationRule rule : columnDefinition.getValidationRules()) {