/****************************************************************************** * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program is distributed in the hope * * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * * or via info@compiere.org or http://www.compiere.org/license.html * * Contributor(s): Teo Sarca *****************************************************************************/ package org.compiere.impexp; import java.math.BigDecimal; import java.math.RoundingMode; import java.sql.Timestamp; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; import org.compiere.model.Callout; import org.compiere.model.X_AD_ImpFormat_Row; import org.compiere.util.CLogger; import org.compiere.util.Env; import org.compiere.util.Util; /** * Import Format Row with parsing capability * * @author Jorg Janke * @author Trifon Trifonov, Catura AG (www.catura.de) *
  • FR [ 3010957 ] Custom Separator Character, https://sourceforge.net/p/adempiere/feature-requests/975/
  • * @version $Id: ImpFormatRow.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ * * globalqss: integrate Teo Sarca bug fix [ 1623817 ] Minor bug on importing calendar date */ public final class ImpFormatRow { /** * Constructor for fixed format * @param seqNo sequence * @param columnName db column name * @param startNo start no * @param endNo and no * @param dataType data type - see constants DATATYPE_ * @param maxLength if String it is the maximum length (truncated) * @param name column label */ public ImpFormatRow(int seqNo, String columnName, int startNo, int endNo, String dataType, int maxLength, String name) { m_seqNo = seqNo; setColumnName(columnName); setName(name); m_startNo = startNo; m_endNo = endNo; setDataType (dataType); setMaxLength (maxLength); } // ImpFormatRow /** * Constructor for non-fixed format * @param seqNo sequence * @param columnName db column name * @param dataType data type - see constants DATATYPE_ * @param maxLength if String it is the maximum length (truncated) */ public ImpFormatRow(int seqNo, String columnName, String dataType, int maxLength) { m_seqNo = seqNo; setColumnName(columnName); setDataType (dataType); setMaxLength (maxLength); } // ImpFormatRow private int m_seqNo; private String m_columnName; private String m_name; private int m_startNo = 0; private int m_endNo = 0; private String m_dataType; private String m_dataFormat = ""; private String m_decimalPoint = "."; private boolean m_divideBy100 = false; private String m_constantValue = ""; private boolean m_constantIsString = true; // private Callout[] m_callout = null; private String[] m_method = null; private String importprefix = ""; // private SimpleDateFormat m_dformat = null; private int m_maxLength = 0; /** Logger */ private static final CLogger log = CLogger.getCLogger(ImpFormatRow.class); /** * Sequence No * @return seq no */ public int getSeqNo () { return m_seqNo; } // getSeqNo /** * Set Sequence No * @param newSeqNo sequence */ public void setSeqNo (int newSeqNo) { m_seqNo = newSeqNo; } // setSeqNo /** * Start Position * @param newStartNo start position */ public void setStartNo (int newStartNo) { m_startNo = newStartNo; } // setStartNo /** * Get Start Position * @return start position */ public int getStartNo() { return m_startNo; } // getStartNo /** * End Position * @param newEndNo end position */ public void setEndNo (int newEndNo) { m_endNo = newEndNo; } // setEndNo /** * Get End Position * @return End Position */ public int getEndNo () { return m_endNo; } // getEndNo /** * Column * @param columnName column name */ public void setColumnName (String columnName) { if (columnName == null || columnName.length() == 0) throw new IllegalArgumentException("ColumnName must be at least 1 char"); else m_columnName = columnName; } // setColumnName /** * Get Column Name * @return Column Name */ public String getColumnName() { return m_columnName; } // getColumnName /** * Name * @param name name */ public void setName (String name) { if (name == null || name.length() == 0) throw new IllegalArgumentException("Name must be at least 1 char"); else m_name = name; } // setName /** * Get Name * @return Name */ public String getName() { return m_name; } // getName /** * Data Type * @param dataType data type - see constants DATATYPE_ */ public void setDataType (String dataType) { if (dataType.equals(X_AD_ImpFormat_Row.DATATYPE_String) || dataType.equals(X_AD_ImpFormat_Row.DATATYPE_Date) || dataType.equals(X_AD_ImpFormat_Row.DATATYPE_Number) || dataType.equals(X_AD_ImpFormat_Row.DATATYPE_Constant)) m_dataType = dataType; else throw new IllegalArgumentException("DataType must be S/D/N/C"); } // setDataType /** * Data Type * @return data type */ public String getDataType() { return m_dataType; } // getDataType /** * Is String * @return true if data type is String */ public boolean isString() { if (m_dataType.equals(X_AD_ImpFormat_Row.DATATYPE_Constant)) return m_constantIsString; return m_dataType.equals(X_AD_ImpFormat_Row.DATATYPE_String); } // isString /** * Is Number * @return true if data type is Number */ public boolean isNumber() { return m_dataType.equals(X_AD_ImpFormat_Row.DATATYPE_Number); } /** * Is Date * @return true if data type is Date */ public boolean isDate() { return m_dataType.equals(X_AD_ImpFormat_Row.DATATYPE_Date); } /** * Is Constant * @return true if data type is Constant */ public boolean isConstant() { return m_dataType.equals(X_AD_ImpFormat_Row.DATATYPE_Constant); } /** * Set Format Info * @param dataFormat data format - see constants DATATYPE_ * @param decimalPoint decimal point representation * @param divideBy100 divide number by 100 * @param constantValue constant value * @param callout Java callout * @param importprefix Prefix to be added if value is not null or empty */ public void setFormatInfo (String dataFormat, String decimalPoint, boolean divideBy100, String constantValue, String callout, String importprefix) { if (dataFormat == null) m_dataFormat = ""; else m_dataFormat = dataFormat; m_dformat = null; // ADD THIS LINE TO RESET date format // number if (decimalPoint == null || !decimalPoint.equals(",")) m_decimalPoint = "."; else m_decimalPoint = ","; m_divideBy100 = divideBy100; // constant if (constantValue == null || constantValue.length() == 0 || !m_dataType.equals(X_AD_ImpFormat_Row.DATATYPE_Constant)) { m_constantValue = ""; m_constantIsString = true; } else { m_constantValue = constantValue; m_constantIsString = false; for (int i = 0; i < m_constantValue.length(); i++) { char c = m_constantValue.charAt(i); if (!(Character.isDigit(c) || c == '.')) // if a constant number, it must be with . (not ,) { m_constantIsString = true; break; } } } // callout if (callout != null) { String[] callouts = callout.split(";"); m_callout = new Callout[callouts.length]; m_method = new String[callouts.length]; for (int i = 0; i < callouts.length; i++) { int methodStart = callouts[i].trim().lastIndexOf('.'); try { if (methodStart != -1) // no class { Class cClass = Class.forName(callouts[i].trim().substring(0,methodStart)); m_callout[i] = (Callout)cClass.getDeclaredConstructor().newInstance(); m_method[i] = callouts[i].trim().substring(methodStart+1); } } catch (Exception e) { throw new AdempiereException(e); } if (m_callout.length == 0 || m_method == null || m_method.length == 0) { log.log(Level.SEVERE, "MTab.setFormatInfo - Invalid Callout " + callout); m_callout = null; } } } //import prefix if (importprefix != null) { this.importprefix = importprefix; } else { this.importprefix = ""; } } // setFormatInfo /** * Get Format * @return Data Format */ public String getDataFormat() { return m_dataFormat; } /** * Get Decimal Point * @return Decimal Point */ public String getDecimalPoint() { return m_decimalPoint; } /** * Divide result by 100 * @return true if result will be divided by 100 */ public boolean isDivideBy100() { return m_divideBy100; } /** * Get the constant value * @return constant value */ public String getConstantValue() { return m_constantValue; } /** * Set maximum length for Strings (truncated). * Ignored, if 0. * @param maxLength max length */ public void setMaxLength (int maxLength) { m_maxLength = maxLength; } // setMaxLength /** * Parse value. * Field content in [] are treated as comments * @param info data item * @return parsed info */ public String parse (String info) { if (info == null || info.length() == 0) return ""; // Comment ? if (info.startsWith("[") && info.endsWith("]")) return ""; // String retValue = null; if (isNumber()) retValue = parseNumber (info); else if (isDate()) retValue = parseDate (info); else if (isConstant()) retValue = m_constantIsString ? parseString (m_constantValue) : m_constantValue; else retValue = parseString (info); // if (m_callout != null && m_callout.length > 0) { try { for (int i = 0; i < m_callout.length; i++) retValue = m_callout[i].convert (m_method[i], retValue); } catch (Exception e) { log.log(Level.SEVERE, "ImpFormatRow.parse - " + info + " (" + retValue + ")", e); } } // if (retValue == null) retValue = ""; return (retValue.trim().length() > 0 ? importprefix : "") + retValue.trim(); } // parse /** * Return date as YYYY-MM-DD HH24:MI:SS (JDBC Timestamp format w/o milliseconds) * @param info data * @return date as JDBC format String */ private String parseDate (String info) { if (m_dformat == null) { try { if (!Util.isEmpty(m_dataFormat)) m_dformat = new SimpleDateFormat(m_dataFormat); } catch (Exception e) { log.log(Level.SEVERE, "ImpFormatRow.parseDate Format=" + m_dataFormat, e); } if (m_dformat == null) m_dformat = (SimpleDateFormat)DateFormat.getDateInstance(); m_dformat.setLenient(true); } Timestamp ts = null; try { ts = new Timestamp (m_dformat.parse(info).getTime()); } catch (ParseException pe) { String msg = pe.getLocalizedMessage() + ": Pattern[" + m_dformat.toPattern() + "] Data[" + info + "]"; throw new AdempiereException(msg); } // String dateString = ts.toString(); return dateString.substring(0, dateString.indexOf('.')); // cut off milliseconds } // parseNumber /** *
    	 *  Return String.
    	 *  - clean ' and backslash
    	 *  - check max length
    	 *  
    * @param info data * @return info with in SQL format */ private String parseString (String info) { String retValue = info; // Length restriction if (m_maxLength > 0 && retValue.length() > m_maxLength) retValue = retValue.substring(0, m_maxLength); // copy characters (wee need to look through anyway) StringBuilder out = new StringBuilder(retValue.length()); for (int i = 0; i < retValue.length(); i++) { char c = retValue.charAt(i); if (c == '\'') out.append("''"); else if (c == '\\') out.append("\\\\"); else out.append(c); } return out.toString(); } // parseString /** * Return number with "." decimal * @param info data * @return converted number */ private String parseNumber (String info) { boolean hasPoint = info.indexOf('.') != -1; boolean hasComma = info.indexOf(',') != -1; // delete thousands if (hasComma && m_decimalPoint.equals(".")) info = info.replace(',', ' '); if (hasPoint && m_decimalPoint.equals(",")) info = info.replace('.', ' '); hasComma = info.indexOf(',') != -1; // replace decimal if (hasComma && m_decimalPoint.equals(",")) info = info.replace(',', '.'); // remove everything but digits & '.' & '-' char[] charArray = info.toCharArray(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < charArray.length; i++) if (Character.isDigit(charArray[i]) || charArray[i] == '.' || charArray[i] == '-') sb.append(charArray[i]); if (sb.length() == 0) return "0"; BigDecimal bd = null; try { bd = new BigDecimal(sb.toString()); } catch (NumberFormatException pe) { log.log(Level.SEVERE, "ImpFormatRow.parseNumber - " + info, pe); } if (bd == null) bd = BigDecimal.ZERO; if (m_divideBy100) // assumed two decimal scale bd = bd.divide(Env.ONEHUNDRED, 2, RoundingMode.HALF_UP); return bd.toString(); } // parseNumber } // ImpFormatFow