package br.com.concretesolutions.canarinho.formatador; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.text.ParsePosition; import java.util.Locale; import java.util.regex.Pattern; /** * Formatador de valores monetários. Possui duas versões: * <ul> * <li>Com símbolo do Real {@link Formatador#VALOR_COM_SIMBOLO}</li> * <li>Sem símbolo do Real {@link Formatador#VALOR}</li> * </ul> */ public final class FormatadorValor implements Formatador { private static final DecimalFormat FORMATADOR_MOEDA = (DecimalFormat) NumberFormat.getCurrencyInstance(new Locale("pt", "BR")); private static final Pattern PADRAO_DECIMAL = Pattern .compile("^\\d+(\\.\\d{1,2})?$"); private static final Pattern PADRAO_MOEDA = Pattern .compile("\\d{1,3}(\\.\\d{3})*(,\\d{2})?"); private static final String SIMBOLO_REAL = "R$ "; static { final DecimalFormatSymbols decimalFormatSymbols = FORMATADOR_MOEDA.getDecimalFormatSymbols(); decimalFormatSymbols.setCurrencySymbol(""); FORMATADOR_MOEDA.setMinimumFractionDigits(2); FORMATADOR_MOEDA.setDecimalFormatSymbols(decimalFormatSymbols); FORMATADOR_MOEDA.setNegativePrefix("-"); FORMATADOR_MOEDA.setNegativeSuffix(""); FORMATADOR_MOEDA.setPositivePrefix(""); FORMATADOR_MOEDA.setParseBigDecimal(true); } private final boolean adicionaSimboloReal; // No instance creation private FormatadorValor(boolean comSimboloReal) { adicionaSimboloReal = comSimboloReal; } /** * Busca uma instância do formatador com símbolo ou sem. * * @param comSimboloReal Flag para saber qual instância buscar. * @return FormatadorValor de acordo com a flag */ static FormatadorValor getInstance(boolean comSimboloReal) { return comSimboloReal ? SingletonHolder.INSTANCE_COM_SIMBOLO : SingletonHolder.INSTANCE_SEM_SIMBOLO; } @Override public String formata(String value) { final String resultado = FORMATADOR_MOEDA.format(new BigDecimal(value)); return adicionaSimboloReal ? SIMBOLO_REAL + resultado : resultado; } @Override public String desformata(String value) { String realValue = value; if (value.startsWith(SIMBOLO_REAL)) { realValue = value.substring(value.indexOf(SIMBOLO_REAL)); } final BigDecimal valor = (BigDecimal) FORMATADOR_MOEDA.parse(realValue, new ParsePosition(0)); return valor.toPlainString(); } @Override public boolean estaFormatado(String value) { if (value == null) { throw new IllegalArgumentException("Valor não pode ser nulo"); } return PADRAO_MOEDA.matcher(value).matches(); } @Override public boolean podeSerFormatado(String value) { if (value == null) { throw new IllegalArgumentException("Valor não pode ser nulo"); } return PADRAO_DECIMAL.matcher(value).matches(); } private static class SingletonHolder { private static final FormatadorValor INSTANCE_SEM_SIMBOLO = new FormatadorValor(false); private static final FormatadorValor INSTANCE_COM_SIMBOLO = new FormatadorValor(true); } }