Java tutorial
/* * 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: 30/03/2008 - 18:16:48 * * ================================================================================ * * Direitos autorais 2008 JRimum Project * * Licenciado sob a Licena Apache, Verso 2.0 ("LICENA"); voc no pode usar * esse arquivo exceto em conformidade com a esta LICENA. Voc pode obter uma * cpia desta LICENA em http://www.apache.org/licenses/LICENSE-2.0 A menos que * haja exigncia legal ou acordo por escrito, a distribuio de software sob * esta LICENA se dar COMO EST??, SEM GARANTIAS OU CONDIES DE QUALQUER * TIPO, sejam expressas ou tcitas. Veja a LICENA para a redao especfica a * reger permisses e limitaes sob esta LICENA. * * Criado em: 30/03/2008 - 18:16:48 * */ package org.jrimum.utilix.text; import static org.jrimum.utilix.Objects.isNotNull; import static org.jrimum.utilix.Objects.isNull; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.Format; import java.text.ParseException; import java.util.Date; import org.apache.commons.lang.StringUtils; import org.jrimum.utilix.Dates; import org.jrimum.utilix.Objects; /** * <p> * Um campo de texto, nmero, data ou outro como <code>TextStream</code>, ou seja, * que se possa ler e escrever. * </p> * * @author <a href="http://gilmatryx.googlepages.com/">Gilmar P.S.L</a> * @author <a href="mailto:misaelbarreto@gmail.com">Misael Barreto</a> * @author <a href="mailto:romulomail@gmail.com">Rmulo Augusto</a> * @author <a href="http://www.nordestefomento.com.br">Nordeste Fomento * Mercantil</a> * * @see TextStream * * @since 0.2 * * @version 0.2 */ public class Field<G> implements TextStream { /** * */ private static final long serialVersionUID = -7432509456997808459L; /** * <p> * Tamanho do campo como string. * </p> */ private Integer length; /** * <p> * Valor do campo. * </p> */ private G value; /** * <p> * Formatador utilizado na leitura e na escrita do value. * </p> * */ private Format format; /** * <p> * Preenchedor do value utilizado na hora da escrita. * </p> */ private Filler<?> filler; /** * <p> * Cria um <code>Field</code> sem um formatador. Isto significa que a * leitura da String pelo objeto criado ser como uma atribuio simples. * </p> * * @param value * Valor do campo * @param length * Tamanho que o value deve possuir. * @since 0.2 */ public Field(G value, Integer length) { setValue(value); setLength(length); } /** * <p> * Cria um <code>Field</code> com um formatador. Isto significa que a * leitura da String pelo objeto criado ser de acordo com o formatador. * </p> * * @param value * Valor do campo * @param length * tamanho do campo * @param format * Formatador que ir formatar a String fornecida na leitura para * o value especificado. * @since 0.2 */ public Field(G value, Integer length, Format format) { setLength(length); setValue(value); setFormat(format); } /** * <p> * Cria um <code>Field</code> com um preenchedor. Este preenchedor * utilizado na escrita do <code>Field</code> quado necessrio preencher * com caracteres especificados at o length definido. * </p> * * @param value * valor do campo * @param length * tamaho do campo * @param filler * preenchedor * @since 0.2 */ public Field(G value, Integer length, Filler<?> filler) { setLength(length); setValue(value); setFiller(filler); } /** * <p> * Cria um <code>Field</code> com um formatador e com um preenchedor. * </p> * * @param value * Valor do campo * @param length * Tamanho do campo * @param format * Formatador que ir formatar a String fornecida na leitura para * o value especificado. * @param filler * preenchedor * @since 0.2 */ public Field(G value, Integer length, Format format, Filler<?> filler) { setLength(length); setValue(value); setFormat(format); setFiller(filler); } /** * <p> * Converte a String fornecida para o value representado pelo objeto. * </p> * <p> * A converso realizada a partir do formatador fornecido para o objeto. * Se no houver formatador a String fornecida ser atribuda como o valor * do value. * </p> * * @param valueAsString * valor do campo como uma String * @since 0.2 */ public void read(String valueAsString) { if (isNull(valueAsString)) { throw new IllegalArgumentException("String invlida [ " + valueAsString + " ]!"); } if (valueAsString.length() != length) { throw new IllegalArgumentException("O tamanho da String [ " + valueAsString + " ] incompatvel com o especificado [ " + length + " ]!"); } if (value instanceof TextStream) { TextStream reader = (TextStream) value; reader.read(valueAsString); } else if (value instanceof BigDecimal) { readDecimalField(valueAsString); } else if (value instanceof Date) { readDateField(valueAsString); } else { readStringOrNumericField(valueAsString); } } /** * L campos texto (String) ou numricos que pode ser obtidos a partir de uma String, * usando, por exemplo, o construtor ou o mtodo <code>valueOf</code>. * * @param valueAsString */ @SuppressWarnings("unchecked") private void readStringOrNumericField(String valueAsString) { Class<?> c = value.getClass(); for (Constructor<?> cons : c.getConstructors()) { if (cons.getParameterTypes().length == 1) { if (cons.getParameterTypes()[0].equals(String.class)) { try { value = (G) cons.newInstance(valueAsString); } catch (IllegalArgumentException e) { getGenericReadError(e, valueAsString).printStackTrace(); } catch (InstantiationException e) { getGenericReadError(e, valueAsString).printStackTrace(); } catch (IllegalAccessException e) { getGenericReadError(e, valueAsString).printStackTrace(); } catch (InvocationTargetException e) { getGenericReadError(e, valueAsString).printStackTrace(); } } } } } /** * L campos do tipo data. O parse feito atravs do formatador do campo. * * @param valueAsString */ @SuppressWarnings("unchecked") private void readDateField(String valueAsString) { try { value = (G) format.parseObject(valueAsString); } catch (ParseException e) { getGenericReadError(e, valueAsString); } } /** * L campos de valores decimais. O parse feito atravs de formatadores de nmeros decimais. * @param valueAsString */ @SuppressWarnings("unchecked") private void readDecimalField(String valueAsString) { DecimalFormat decimalFormat = (DecimalFormat) format; try { Long parsedValue = (Long) format.parseObject(valueAsString); BigDecimal decimalValue = new BigDecimal(parsedValue.longValue()); decimalValue = decimalValue.movePointLeft(decimalFormat.getMaximumFractionDigits()); value = (G) decimalValue; } catch (ParseException e) { getGenericReadError(e, valueAsString); } } /** * <p> * Escreve o campo no formato e tamanho especificado. * </p> * * @see TextStream#write() * * @return campo escrito * @since 0.2 */ public String write() { String str = null; if (value instanceof TextStream) { TextStream its = (TextStream) value; str = its.write(); } else if (value instanceof Date) { Date campoDate = (Date) value; if (Dates.equalsInvalidDate(campoDate)) { str = StringUtils.EMPTY; } else { str = format.format(value); } } else if (value instanceof BigDecimal) { str = StringUtils.replaceChars(value.toString(), ".", StringUtils.EMPTY); } else { str = value.toString(); } str = fill(str); if (str.length() != length) { throw new IllegalArgumentException( "O tamaho do campo [ " + str + " ] incompatvel com o especificado [" + length + "]!"); } return Strings.eliminateAccent(str).toUpperCase(); } /** * Preenche a string passada de acordo com o filler do campo. * @param str * @return */ private String fill(String str) { if (isNotNull(filler)) { str = filler.fill(str, length); } return str; } /** * <p> * Retorna o valor que o campo contm. * </p> * * @return objeto valor do campo * * @since 0.2 */ public G getValue() { return value; } /** * <p> * Atribui um valor a instncia. * </p> * * @param field * * @since 0.2 */ public void setValue(G field) { if (isNotNull(field)) { this.value = field; } else { throw new IllegalArgumentException("Campo invlido [" + field + "]!"); } } /** * <p> * Tamanho do campo como string. * </p> * * @return * * @since 0.2 */ public Integer getLength() { return length; } /** * <p> * Atribui um tamanho (maior que zero) a instncia. * </p> * * @param length * * @since 0.2 */ public void setLength(Integer length) { if (length > 0) { this.length = length; } else { throw new IllegalArgumentException("Tamanho invlido [ " + length + " ]!"); } } /** * <p> * Formatador utilizado na leitura e na escrita do value. * </p> * * <p> * <ul> * <li>Na leitura para realizar o <code>parse</code> da String.</li> * <li>Na escrita para transformar o objeto em uma String e assim ser * possvel trat-la para ser escrita.</li> * </ul> * </p> * * @return formatador * * @since 0.2 */ public Format getFormat() { return format; } /** * <p> * Atribui um formatador a instncia. * </p> * * @param format * * @since 0.2 */ public void setFormat(Format format) { if (isNotNull(format)) { this.format = format; } else { throw new IllegalArgumentException("Formato invlido [ " + format + " ]!"); } } /** * <p> * Retorna o preenchedor do campo. * </p> * * @return preenchedor * * @since 0.2 */ public Filler<?> getFiller() { return filler; } /** * <p> * Atribui um preenchedor a instncia. * </p> * * @param filler * * @since 0.2 */ public void setFiller(Filler<?> filler) { if (isNotNull(filler)) { this.filler = filler; } else { throw new IllegalArgumentException("Filler invlido [ " + filler + " ]!"); } } /** * Formata a exceo caso ela ocorra na leitura do campo. * @param e * @param value * @return */ private static Exception getGenericReadError(Exception e, String value) { StackTraceElement[] stackTrace = e.getStackTrace(); e = new RuntimeException("VALOR INV?LIDO [ " + value + " ]!\nCausado por: " + e.getCause()); e.setStackTrace(stackTrace); return e; } /** * @see Objects#toString() */ @Override public String toString() { return Objects.toString(this); } }