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

org.jrimum.texgit.Field Maven / Gradle / Ivy

Go to download

This is a fork and merge from JRimum ( http://www.jrimum.org ), - Bopepo: https://github.com/jrimum/bopepo - Texgit: https://github.com/jrimum/texgit - Valia: https://github.com/jrimum/vallia - Utilix: https://github.com/jrimum/utilix - Domkee: https://github.com/jrimum/domkee For Brazillian Boleto Payment Method. So much thanks for original authors: Gilmar P. S. L, Misael Barreto and Rômulo Augusto.

The newest version!
/*
 * Copyright 2008 JRimum Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
 * applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, either express or implied. See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * Created at: 26/07/2008 - 12:44:41
 *
 * ================================================================================
 *
 * Direitos autorais 2008 JRimum Project
 *
 * Licenciado sob a Licença Apache, Versão 2.0 ("LICENÇA"); você não pode usar
 * esse arquivo exceto em conformidade com a esta LICENÇA. Você pode obter uma
 * cópia desta LICENÇA em http://www.apache.org/licenses/LICENSE-2.0 A menos que
 * haja exigência legal ou acordo por escrito, a distribuição de software sob
 * esta LICENÇA se dará “COMO ESTÁ”, SEM GARANTIAS OU CONDIÇÕES DE QUALQUER
 * TIPO, sejam expressas ou tácitas. Veja a LICENÇA para a redação específica a
 * reger permissões e limitações sob esta LICENÇA.
 *
 * Criado em: 26/07/2008 - 12:44:41
 *
 */
package org.jrimum.texgit;

import static java.lang.String.format;

import java.lang.reflect.Constructor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Date;

import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNumeric;
import org.jrimum.utilix.Dates;
import static org.jrimum.utilix.ObjectUtil.isNotNull;
import org.jrimum.utilix.Objects;
import org.jrimum.utilix.StringUtil;

/**
 * @author Gilmar P.S.L.
 *
 * @param 
 */
@SuppressWarnings("serial")
public class Field implements org.jrimum.texgit.IField, TextStream {

    /**
     * 

* Nome do campo, também pode ser usado como id. *

*/ protected String name; /** * */ protected Integer length; /** *

* Valor do campo. *

*/ private G value; /** *

* Formatador utilizado na leitura e escrita do valor do campo. *

*/ private Format formatter; /** * Preenchedor do value utilizado na hora da escrita. */ protected IFiller filler; /** *

* Necessário para ler campos númericos em branco. *

*/ private boolean blankAccepted; /** *

* Ao ultrapassar o tamanho, define se pode truncar ou se dispara uma * exceção. *

*/ protected boolean truncate; /** *

* Quando definido, todos os caracteres não numericos são desprezados/removidos *

*/ protected boolean apenasDigitos; /** * */ public Field() { super(); } /** * @param value */ public Field(G value) { super(); setValue(value); } /** *

* Cria um Field com um valor e um formatador para o valor. * Isto significa que a leitura e escrita do valor informado será de acordo * com o formatador. *

* * @param value * @param formatter */ public Field(G value, Format formatter) { setValue(value); setFormatter(formatter); } /** * @param name * @param value */ public Field(String name, G value) { super(); setName(name); setValue(value); } /** *

* Cria um Field com nome para identificação, valor e um * formatador. *

* * @param name * @param value * @param formatter * * @see #Field(Object, Format) */ public Field(String name, G value, Format formatter) { setName(name); setValue(value); setFormatter(formatter); } @SuppressWarnings("unchecked") @Override public Field clone() throws CloneNotSupportedException { return (Field) super.clone(); } //Problema: https://stackoverflow.com/questions/3403909/get-generic-type-of-class-at-runtime // public void read(String str) { Objects.checkNotNull(str, "String inválida [null]!"); if (str.length() != length) { throw new IllegalArgumentException("O tamanho da String [ " + str + " ] é incompatível com o especificado [ " + length + " ]!"); } //Tentar inferir o tipo generico do Field //Melhorar isso, pois todas as formas são problematicas //https://stackoverflow.com/questions/3403909/get-generic-type-of-class-at-runtime //O ideal seria fixar uma campo com o valor da Class generica. Class valueType = String.class;//Tipo padrão try { if (value != null) { valueType = value.getClass(); } else { Class tmpValueType = getGenericTypeArgument(this.getClass(), 0); if (tmpValueType != null) { valueType = tmpValueType; } } } catch (Exception e) { } try { if (this.value instanceof TextStream || TextStream.class.isAssignableFrom(valueType)) { TextStream reader = (TextStream) this.value; reader.read(str); } else if (this.value instanceof BigDecimal || BigDecimal.class.isAssignableFrom(valueType)) { readDecimalField(str); } else if (this.value instanceof Date || Date.class.isAssignableFrom(valueType)) { readDateField(str); } else if (this.value instanceof Character || Character.class.isAssignableFrom(valueType)) { readCharacter(str); } else if (this.value instanceof Number || Number.class.isAssignableFrom(valueType)) { readNumeric(valueType, str); } else { readStringOrNumericField(str); } } catch (Exception e) { throw new IllegalStateException(format("Falha na leitura do campo! %s", toString()), e); } } @SuppressWarnings("unchecked") private void readCharacter(String str) { if (str.length() == 1) { value = (G) new Character(str.charAt(0)); } else { throw new IllegalArgumentException("String com mais de 1 character!"); } } @SuppressWarnings("unchecked") private void readDecimalField(String str) { DecimalFormat decimalFormat = (DecimalFormat) formatter; try { String number = parseNumber(str); Long parsedValue = (Long) formatter.parseObject(number); BigDecimal decimalValue = new BigDecimal(parsedValue.longValue()); decimalValue = decimalValue.movePointLeft(decimalFormat.getMaximumFractionDigits()); value = (G) decimalValue; } catch (ParseException e) { throwReadError(e, str); } } @SuppressWarnings("unchecked") private void readDateField(String str) { try { if (isBlank(str)) { if (isBlankAccepted()) { value = (G) Dates.invalidDate(); } else { new IllegalArgumentException(format("Campo data vazio não permitido: [%s]!", str)); } } else { value = (G) formatter.parseObject(str); } } catch (ParseException e) { throwReadError(e, str); } } @SuppressWarnings("unchecked") private void readStringOrNumericField(String str) { str = parseNumber(str); // if (value != null && value.getClass().equals(String.class)) { value = (G) str; // } else { // readNumeric(clazz, str); // } } public static Class getGenericTypeArgument(final Class clazz, final int idx) { final Type type = clazz.getGenericSuperclass(); ParameterizedType paramType; try { paramType = (ParameterizedType) type; } catch (ClassCastException cause) { paramType = (ParameterizedType) ((Class) type).getGenericSuperclass(); } return (Class) paramType.getActualTypeArguments()[idx]; } @SuppressWarnings("unchecked") private void readNumeric(Class clazz, String str) { for (Constructor cons : clazz.getConstructors()) { if (cons.getParameterTypes().length == 1) { if (cons.getParameterTypes()[0].equals(String.class)) { try { value = (G) cons.newInstance(str); } catch (Exception e) { throwReadError(e, str); } } } } } protected String truncate(String str) { if (truncate && length != null && str.length() > length) { str = str.substring(0, length); } return str; } protected String fill(String str) { if (length != null && isNotNull(filler)) { str = filler.fill(str, length); } return str; } public String write() { try { String str = null; if (value instanceof TextStream) { TextStream its = (TextStream) value; str = its.write(); } else if (value instanceof Date) { str = writeDateField(); } else if (value instanceof Number) { str = writeDecimalField(); } else { str = value.toString(); } if (this.apenasDigitos) { str = StringUtil.eliminateSymbols(str); } str = fill(str); if (length != null && str.length() != length) { if (!truncate) { throw new IllegalArgumentException("O campo [ " + str + " ] é incompatível com o especificado [" + length + "]!"); } } return StringUtil.eliminateAccent(str).toUpperCase(); } catch (Exception e) { throw new IllegalStateException(format("Falha na escrita do campo escrita! %s", toString()), e); } } private String writeDecimalField() { String ret = "" + value; if (value instanceof BigDecimal) { BigDecimal decimalValue = (BigDecimal) value; if (formatter == null) { formatter = NumberFormat.getInstance(); } decimalValue = decimalValue.movePointRight(((DecimalFormat) formatter).getMaximumFractionDigits()); ret = decimalValue.toString(); } else if (value instanceof Number && formatter != null) { ret = formatter.format(value); } return ret; } private String writeDateField() { if (!Dates.equalsInvalidDate((Date) value)) { return formatter.format(value); } return EMPTY; } private String parseNumber(String str) { if (isBlank(str)) { if (isBlankAccepted()) { str = "0"; } else { new IllegalArgumentException(format("Campo numérico vazio não permitido: [%s]!", str)); } } else if (!isNumeric(str)) { new IllegalArgumentException(format("O campo deve ser numérico e não: [%s]!", str)); } return str; } public String getName() { return name; } public void setName(String name) { if (isNotNull(name)) { this.name = name; } else { throw new IllegalArgumentException(format("Nome Inválido: [%s]!", name)); } } public boolean isBlankAccepted() { return this.blankAccepted; } public void setBlankAccepted(boolean blankAccepted) { this.blankAccepted = blankAccepted; } public G getValue() { return value; } public void setValue(G value) { if (isNotNull(value)) { this.value = value; } else { throw new IllegalArgumentException(format("Valor Inválido: [%s]!", value)); } } public Integer getLength() { return length; } public void setLength(Integer length) { if (length > 0) { this.length = length; } else { throw new IllegalArgumentException("Tamanho inválido [ " + length + " ]!"); } } public Format getFormatter() { return formatter; } public void setFormatter(Format formatter) { if (isNotNull(formatter)) { this.formatter = formatter; } else { throw new IllegalArgumentException(format("Formato inválido: [%s]!", formatter)); } } public IFiller getFiller() { return filler; } public void setFiller(Filler filler) { if (isNotNull(filler)) { this.filler = filler; } else { throw new IllegalArgumentException("Filler inválido [ " + filler + " ]!"); } } private void throwReadError(Exception e, String value) { throw new IllegalArgumentException(format("Falha na leitura da string: [\"%s\"]! %s", value, toString()), e); } @Override public String toString() { return format("Field [name=\"%s\", value=\"%s\", isBlankAccepted=%s, apenasDigitos=%s, formatter=%s]", Objects.whenNull(this.name, EMPTY), Objects.whenNull(this.value, EMPTY), this.apenasDigitos, Objects.whenNull(this.isBlankAccepted(), EMPTY), Objects.whenNull(this.formatter, EMPTY)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy