All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.codecamp.messages.shared.messageformat.DefaultMessageFormatSupport Maven / Gradle / Ivy

There is a newer version: 2.1.0
Show newest version
package de.codecamp.messages.shared.messageformat;

import java.text.ChoiceFormat;
import java.text.DateFormat;
import java.text.Format;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Deque;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import de.codecamp.messages.MessageKeyWithArgs;


/**
 * Implements {@link MessageFormatSupport} for {@link MessageFormat Java's MessageFormat}.
 * 

* If changes are made to the checked types, this must be reflected in * {@link de.codecamp.messages.runtime.DefaultMessageArgConverter}. */ public class DefaultMessageFormatSupport implements MessageFormatSupport { public static final String ID = "classic"; private static final Set NUMBER_FORMAT_TYPE_NAME_MAPPING = new HashSet<>(); static { NUMBER_FORMAT_TYPE_NAME_MAPPING.addAll(Arrays.asList(Number.class.getName())); } private static final Set DATE_FORMAT_TYPE_NAME_MAPPING = new HashSet<>(); static { DATE_FORMAT_TYPE_NAME_MAPPING.addAll( Arrays.asList(Date.class.getName(), Calendar.class.getName(), Number.class.getName(), // java.time types LocalDate.class.getName(), LocalTime.class.getName(), LocalDateTime.class.getName(), ZonedDateTime.class.getName(), OffsetTime.class.getName(), OffsetDateTime.class.getName(), Instant.class.getName())); } @Override public boolean supportsFormat(String messageFormat) { return ID.equals(messageFormat); } @Override public boolean hasArgNameSupport() { return false; } @Override public List getArgInsertOptions(MessageKeyWithArgs key) { List result = new ArrayList<>(); String[] argTypes = key.getArgTypes(); String[] argNames = key.getArgNames(); for (int i = 0; i < argTypes.length; i++) { String label = argNames[i] + " : " + formatArgType(argTypes[i]); String reference = "{" + i + "}"; result.add(new ArgInsert(label, reference)); } return result; } @Override public String createMessageBundleComment(MessageKeyWithArgs key) { String comment; if (key.hasArgs()) { String[] argTypes = key.getArgTypes(); String[] argNames = key.getArgNames(); StringBuilder messageArgComment = new StringBuilder(); messageArgComment.append("Arguments: "); boolean first = true; for (int i = 0; i < argTypes.length; i++) { if (first) first = false; else messageArgComment.append(" | "); messageArgComment.append(argNames[i]).append(":"); messageArgComment.append(formatArgType(argTypes[i])); messageArgComment.append(" -> "); messageArgComment.append("{").append(i).append("}"); } comment = messageArgComment.toString(); } else { comment = null; } return comment; } @Override public List checkMessage(String message, String[] argTypes, String[] argNames, TypeChecker argTypeChecker) { List errors = new ArrayList<>(); int usedArgCount = 0; if (argTypes != null && argTypes.length > 0) { Deque messageParts = new ArrayDeque<>(); messageParts.addLast(message); while (!messageParts.isEmpty()) { String messagePart = messageParts.removeFirst(); MessageFormat messageFormat; try { messageFormat = new MessageFormat(messagePart); } catch (IllegalArgumentException ex) { errors.add(String.format("The message is not a valid pattern: %s", ex.getMessage())); return errors; } Format[] argFormats = messageFormat.getFormatsByArgumentIndex(); if (argFormats.length > usedArgCount) usedArgCount = argFormats.length; for (int argIndex = 0; argIndex < argFormats.length; argIndex++) { Format argFormat = argFormats[argIndex]; if (argFormat == null) // no explicit format or not referenced in the first place continue; // is referenced index even declared? if (argIndex >= argTypes.length) continue; if (argFormat instanceof ChoiceFormat) { for (Object f : ((ChoiceFormat) argFormat).getFormats()) messageParts.addLast((String) f); } String argTypeName = argTypes[argIndex]; // ChoiceFormat is also a NumberFormat if (argFormat instanceof NumberFormat) { if (!argTypeChecker.isCompatibleWith(argTypeName, NUMBER_FORMAT_TYPE_NAME_MAPPING)) { errors.add(String.format( "The message expects a number at index %d instead of the declared type: %s", argIndex, argTypeName)); } } else if (argFormat instanceof DateFormat) { if (!argTypeChecker.isCompatibleWith(argTypeName, DATE_FORMAT_TYPE_NAME_MAPPING)) { errors.add(String.format( "The message expects a date at index %d instead of the declared type: %s", argIndex, argTypeName)); } } } } } int argCount = argTypes == null ? 0 : argTypes.length; if (usedArgCount > argCount) { errors.add(String.format("The message uses more arguments (%d) than are declared (%d)", usedArgCount, argCount)); } return errors; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy