Class OpenApiUiUtils

java.lang.Object
org.praxisplatform.uischema.util.OpenApiUiUtils

public class OpenApiUiUtils extends Object

Utilitarios centrais para transformacao OpenAPI → UI metadata

Classe utilitaria que concentra regras de traducao entre schemas OpenAPI e extensoes metadata-driven x-ui. Ela e uma peca central do pipeline que sai das anotacoes backend, passa pelo resolver OpenAPI e chega ao contrato consumido por frontends dinamicos.

Responsabilidades

  • Inferir labels e control types a partir de tipos, formatos e heuristicas.
  • Preencher mapas x-ui de forma consistente e defensiva.
  • Aplicar defaults de UX sem sobrescrever configuracoes explicitas vindas do dominio.

Fluxo arquitetural

 Annotation -> CustomOpenApiResolver -> OpenApiUiUtils -> x-ui
 
Since:
1.0.0
  • Method Details

    • formatFieldNameAsLabel

      public static String formatFieldNameAsLabel(String fieldName)

      Formata um nome de campo técnico (camelCase ou snake_case) em um label legível para humanos.

      Este método é crucial para a experiência do usuário, pois converte nomes de variáveis como "userName" ou "user_name" em "User Name", que é muito mais apresentável em formulários e tabelas da UI.

      Lógica de Transformação:

      1. Substitui underscores (_) por espaços.
      2. Insere um espaço antes de cada letra maiúscula (exceto a primeira) para separar palavras em camelCase.
      3. Converte a primeira letra de cada palavra para maiúscula.
      Parameters:
      fieldName - O nome do campo a ser formatado (ex: "firstName", "last_name", "userAddress").
      Returns:
      Uma string formatada como label (ex: "First Name", "Last Name", "User Address"). Retorna uma string vazia se a entrada for nula ou vazia.

      Exemplos de Uso:

      
       formatFieldNameAsLabel("nomeCompletoDoUsuario") // Retorna "Nome Completo Do Usuario"
       formatFieldNameAsLabel("user_email_address")    // Retorna "User Email Address"
       formatFieldNameAsLabel("id")                    // Retorna "Id"
       

      Considerações Técnicas:

      O método é projetado para ser robusto e lidar com diferentes convenções de nomenclatura de forma consistente. É um dos métodos mais utilizados em toda a aplicação para garantir a padronização de labels.

    • determineBasicControlType

      public static String determineBasicControlType(String openApiType, String openApiFormat, boolean hasEnum, Integer maxLength, boolean isArrayType, boolean isArrayItemsHaveEnum)
      Determina um tipo de controle de UI básico com base nas propriedades do schema OpenAPI.

      Este método serve como a primeira camada de detecção, mapeando diretamente os tipos e formatos do OpenAPI para os tipos de controle de UI mais comuns. A lógica aqui não considera o nome do campo, focando apenas na estrutura do schema.

      Parameters:
      openApiType - O tipo do schema OpenAPI (ex: "string", "number", "boolean").
      openApiFormat - O formato do schema (ex: "date", "email", "password").
      hasEnum - Verdadeiro se a propriedade tiver uma lista de valores `enum`.
      maxLength - O `maxLength` para campos do tipo string, usado para decidir entre `INPUT` e `TEXTAREA`.
      isArrayType - Verdadeiro se o tipo do schema for "array".
      isArrayItemsHaveEnum - Verdadeiro se os itens de um array tiverem uma lista `enum`.
      Returns:
      O valor string de um FieldControlType adequado, ou `null` se nenhum tipo específico for determinado.
    • populateUiGroup

      public static void populateUiGroup(Map<String,Object> xUiMap, String group)
    • populateUiOrder

      public static void populateUiOrder(Map<String,Object> xUiMap, int order)
    • populateUiWidth

      public static void populateUiWidth(Map<String,Object> xUiMap, String width)
    • populateUiIcon

      public static void populateUiIcon(Map<String,Object> xUiMap, String icon)
    • populateUiDisabled

      public static void populateUiDisabled(Map<String,Object> xUiMap, boolean disabled)
    • populateUiHidden

      public static void populateUiHidden(Map<String,Object> xUiMap, boolean hidden)
    • populateUiEditable

      public static void populateUiEditable(Map<String,Object> xUiMap, boolean editable)
    • populateUiSortable

      public static void populateUiSortable(Map<String,Object> xUiMap, boolean sortable)
    • populateUiFilterable

      public static void populateUiFilterable(Map<String,Object> xUiMap, boolean filterable)
    • populateUiHelpText

      public static void populateUiHelpText(Map<String,Object> xUiMap, String description)
    • populateUiDefaultValue

      public static void populateUiDefaultValue(Map<String,Object> xUiMap, Object example)
    • populateUiReadOnly

      public static void populateUiReadOnly(Map<String,Object> xUiMap, Boolean readOnly)
    • populateUiOptionsFromEnum

      public static void populateUiOptionsFromEnum(Map<String,Object> xUiMap, List<?> enumValues, com.fasterxml.jackson.databind.ObjectMapper objectMapper)
      Popula a propriedade `options` no mapa `x-ui` a partir de uma lista de valores `enum` do schema.

      Este método converte uma lista de valores (geralmente strings) em uma estrutura JSON de `[{label: "...", value: "..."}]`, que é o formato esperado por componentes de UI como Selects, Radio Buttons ou Checkbox Groups.

      Parameters:
      xUiMap - O mapa de metadados `x-ui`.
      enumValues - A lista de valores extraída da propriedade `enum` do schema OpenAPI.
      objectMapper - Uma instância de ObjectMapper para construir os nós JSON.
    • populateUiOptionsFromString

      public static void populateUiOptionsFromString(Map<String,Object> xUiMap, String options, com.fasterxml.jackson.databind.ObjectMapper objectMapper)
    • populateUiMinLength

      public static void populateUiMinLength(Map<String,Object> xUiMap, Integer minLength, String message)
    • populateUiMaxLength

      public static void populateUiMaxLength(Map<String,Object> xUiMap, Integer maxLength, String message)
    • populateUiMinimum

      public static void populateUiMinimum(Map<String,Object> xUiMap, Number minimum, String message)
    • populateUiMaximum

      public static void populateUiMaximum(Map<String,Object> xUiMap, Number maximum, String message)
    • populateUiPattern

      public static void populateUiPattern(Map<String,Object> xUiMap, String pattern, String message)
    • populateUiRequired

      public static void populateUiRequired(Map<String,Object> xUiMap, Boolean required)
    • populateUiAllowedFileTypes

      public static void populateUiAllowedFileTypes(Map<String,Object> xUiMap, String contentMediaType)
    • populateUiMaxFileSize

      public static void populateUiMaxFileSize(Map<String,Object> xUiMap, Long maxFileSize)
    • populateUiPlaceholder

      public static void populateUiPlaceholder(Map<String,Object> xUiMap, String titleOrPlaceholder)
    • populateUiName

      public static void populateUiName(Map<String,Object> xUiMap, String fieldName)
    • populateUiLabel

      public static void populateUiLabel(Map<String,Object> xUiMap, String labelText, String fieldName)
      Popula o label do campo no mapa `x-ui`, usando um label explícito ou formatando o nome do campo.
      Parameters:
      xUiMap - O mapa de metadados `x-ui`.
      labelText - O texto do label explícito (vindo de uma anotação, por exemplo). Tem prioridade.
      fieldName - O nome técnico do campo, usado como fallback para gerar um label legível.
    • formatFileSize

      public static String formatFileSize(Object size)
      Formata um tamanho de arquivo em bytes para um formato legível (KB, MB, GB).
      Parameters:
      size - O tamanho do arquivo, geralmente um Long ou String representando bytes.
      Returns:
      Uma string formatada e legível (ex: "1.25 MB").
    • formatAllowedTypes

      public static String formatAllowedTypes(String allowedTypes)
      Formata uma string de mimetypes em uma lista legível para o usuário.

      Converte mimetypes comuns como "application/pdf" para nomes amigáveis como "PDF".

      Parameters:
      allowedTypes - A string de tipos permitidos (ex: "image/jpeg", "image/png").
      Returns:
      Uma string formatada para exibição (ex: "JPEG, JPG").
    • determineFieldDataType

      public static String determineFieldDataType(String openApiType, String openApiFormat)
      Determina o tipo de dado semântico de um campo com base no tipo e formato do schema OpenAPI.

      Este método mapeia os tipos primitivos do OpenAPI para um conjunto de tipos de dados semânticos definidos no enum FieldDataType, como TEXT, NUMBER, DATE, etc. Isso ajuda o frontend a entender como processar e validar o valor do campo.

      Parameters:
      openApiType - O tipo do schema OpenAPI (ex: "string", "integer").
      openApiFormat - O formato do schema OpenAPI (ex: "date-time", "email").
      Returns:
      O valor string de um FieldDataType correspondente, ou `null` se não houver um mapeamento direto.
    • populateUiDataType

      public static void populateUiDataType(Map<String,Object> xUiMap, String openApiType, String openApiFormat)
    • determineSmartControlTypeByFieldName

      public static String determineSmartControlTypeByFieldName(String fieldName)

      Determina um tipo de controle de UI "inteligente" baseado em convenções de nomenclatura de campos.

      Este método implementa a lógica de convenção sobre configuração. Ele analisa o nome de um campo para inferir um tipo de controle de UI mais específico do que o determinado pelas propriedades do schema. Por exemplo, um campo `string` chamado "descricao" é melhor representado como `TEXTAREA` do que um `INPUT` padrão.

      A detecção não é sensível a maiúsculas/minúsculas.

      Parameters:
      fieldName - O nome do campo a ser analisado (ex: "descricao", "valorUnitario", "userPassword").
      Returns:
      O valor string de um FieldControlType sugerido pela convenção, ou `null` se nenhuma convenção for encontrada.

      Exemplos de Mapeamento por Convenção:

    • determineArrayItemFilterControlType

      public static String determineArrayItemFilterControlType(String fieldName, String itemType, String itemFormat)
    • determineEnumControlBySize

      public static String determineEnumControlBySize(int count)
      Determina controle ideal para enums de string por cardinalidade. Pequeno (≤5): radio; Médio (≤25): select; Grande (>25): autoComplete.
    • determineArrayEnumControlBySize

      public static String determineArrayEnumControlBySize(int count)
      Determina controle para arrays de enums: pequeno → chipInput; demais → multiSelect.
    • applyPercentDefaults

      public static void applyPercentDefaults(Map<String,Object> xUiMap)
      Aplica defaults amigáveis para percent (0–100%). Apenas define se ausentes.
    • numericStepFromDigits

      public static String numericStepFromDigits(int fraction)
      Retorna step numérico como string a partir do número de casas decimais. Ex.: fraction=2 → "0.01".
    • determineEffectiveControlType

      public static String determineEffectiveControlType(String openApiType, String openApiFormat, boolean hasEnum, Integer maxLengthSchema, boolean isArrayType, String itemType, String itemFormat, boolean isArrayItemsHaveEnum, String fieldName)

      Algoritmo Principal de Detecção de Tipo de Controle de UI

      Este é o método central que determina o tipo de controle de UI mais apropriado para um campo, orquestrando várias estratégias de detecção em uma ordem de precedência específica.

      Lógica de Precedência:

      1. Detecção Básica: Primeiro, determineBasicControlType(java.lang.String, java.lang.String, boolean, java.lang.Integer, boolean, boolean) é chamado, usando propriedades do schema OpenAPI (type, format, enum) para uma determinação inicial.
      2. Sobrescrita por Filtro de Array: Se o campo for um array e o nome sugerir um filtro (ex: "dataFiltro"), o tipo de controle pode ser especializado para um controle de range (ex: "date-range").
      3. Sobrescrita por Detecção Inteligente (Convenção): Finalmente, determineSmartControlTypeByFieldName(java.lang.String) é chamado. Se encontrar uma correspondência baseada no nome do campo (ex: "descricao" -> "textarea"), este resultado terá a maior precedência e sobrescreverá os anteriores.
      Parameters:
      openApiType - O tipo do schema OpenAPI (ex: "string").
      openApiFormat - O formato do schema OpenAPI (ex: "date-time").
      hasEnum - Flag indicando se o schema possui uma lista de valores `enum`.
      maxLengthSchema - O valor de `maxLength` definido no schema.
      isArrayType - Flag indicando se o tipo do schema é "array".
      itemType - O tipo dos itens, caso o schema seja um array.
      itemFormat - O formato dos itens, caso o schema seja um array.
      isArrayItemsHaveEnum - Flag indicando se os itens do array possuem `enum`.
      fieldName - O nome do campo (ex: "observacao", "dataAdmissao").
      Returns:
      O valor string do FieldControlType efetivo (ex: "textarea", "date-picker").

      Exemplo de Fluxo:

      
       // Campo: "observacao", Tipo: "string", maxLength: 500
      
       // 1. determineBasicControlType("string", null, false, 500, ...) -> "textarea" (devido ao maxLength)
       // 2. (Não é um filtro de array)
       // 3. determineSmartControlTypeByFieldName("observacao") -> "textarea"
      
       // Resultado Final: "textarea"
      
       // ---
      
       // Campo: "status", Tipo: "string", Enum: ["ATIVO", "INATIVO"]
      
       // 1. determineBasicControlType("string", null, true, ...) -> "select"
       // 2. (Não é um filtro de array)
       // 3. determineSmartControlTypeByFieldName("status") -> null
      
       // Resultado Final: "select"
       
      See Also:
    • populateUiControlType

      public static void populateUiControlType(Map<String,Object> xUiMap, String controlType)
      Popula o tipo de controle de UI no mapa `x-ui`.
      Parameters:
      xUiMap - O mapa de metadados `x-ui` a ser populado.
      controlType - O valor do FieldControlType a ser definido.
    • getFieldLabel

      public static String getFieldLabel(Map<String,Object> xUiMap)
      Gets the field label from the UI map for use in validation messages.
      Parameters:
      xUiMap - The UI map.
      Returns:
      The label or a default string "O campo".
    • populateDefaultValidationMessages

      public static void populateDefaultValidationMessages(Map<String,Object> xUiMap)
      Popula o mapa `x-ui` com mensagens de validação padrão e amigáveis.

      Este método gera mensagens de erro para validações comuns (required, minLength, pattern, etc.) caso nenhuma mensagem customizada tenha sido fornecida. Ele utiliza o label do campo para criar mensagens contextuais, como "Nome é obrigatório".

      Parameters:
      xUiMap - O mapa de metadados `x-ui` que contém as propriedades de validação e onde as mensagens serão inseridas.