/* * codjo.net * * Common Apache License 2.0 */ package net.codjo.operation.imports; import net.codjo.model.Period; import net.codjo.model.Table; import net.codjo.operation.Behavior; import net.codjo.operation.Operation; import net.codjo.persistent.PersistenceException; import net.codjo.persistent.Reference; import net.codjo.utils.QueryHelper; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * Comportement d'import. * * <p> * Cette classe definit le comportement d'import d'une op�ration. * </p> * * @author $Author: marcona $ * @version $Revision: 1.5 $ * */ public class ImportBehavior extends Behavior { private String commentry; private List fieldImportList = new ArrayList(); private String fieldSeparator; private String fileType; private ImportFilter filter; private boolean fixedLength; private boolean fixedReadLine = true; private boolean headerLine; private String inBox; private String location; private String outBox; private int recordLength; private String stdFileName; /** * Constructeur. Les arguments correspondent aux champs de la table * PM_IMPORT_SETTINGS * * @param selfRef Self Reference * @param fileType - * @param stdFileName - * @param location - * @param recordLength - * @param commentry - * @param outBox - * @param inBox - * @param fixedLength - * @param fieldSeparator - * @param headerLine - * @param destTable Description of Parameter */ public ImportBehavior(Reference selfRef, String fileType, String stdFileName, String location, int recordLength, String commentry, String outBox, String inBox, boolean fixedLength, String fieldSeparator, boolean headerLine, Table destTable) { super(selfRef, null, destTable); init(fileType, stdFileName, location, recordLength, commentry, outBox, inBox, fixedLength, fieldSeparator, headerLine); } /** * Constructeur pour les tests. * * <p> * Les arguments correspondent aux champs de la table PM_IMPORT_SETTINGS * </p> * * @param fileType - * @param stdFileName - * @param location - * @param recordLength - * @param commentry - * @param outBox - * @param inBox - * @param fixedLength - * @param fieldSeparator - * @param headerLine - * @param destTable Description of Parameter */ ImportBehavior(String fileType, String stdFileName, String location, int recordLength, String commentry, String outBox, String inBox, boolean fixedLength, String fieldSeparator, boolean headerLine, Table destTable) { super(null, destTable); init(fileType, stdFileName, location, recordLength, commentry, outBox, inBox, fixedLength, fieldSeparator, headerLine); } /** * Overview. * * <p> * Description * </p> * * @param fileName Description of Parameter * @param currentPeriod Description of Parameter * * @return Description of the Returned Value * * @exception BadFormatException Description of Exception */ public static File findRealFileName(File fileName, Period currentPeriod) throws BadFormatException { List listFormatIN = new ArrayList(4); listFormatIN.add("aaaa"); listFormatIN.add("mmaa"); listFormatIN.add("aamm"); listFormatIN.add("aa"); List listFormatOUT = new ArrayList(4); listFormatOUT.add("yyyy"); listFormatOUT.add("MMyy"); listFormatOUT.add("yyMM"); listFormatOUT.add("yy"); StringBuffer tmp = new StringBuffer(fileName.toString()); int idx = 0; int cpt = 0; do { idx = tmp.toString().indexOf(listFormatIN.get(cpt).toString()); cpt++; } while ((idx < 0) && (cpt < listFormatIN.size())); if (idx >= 0) { SimpleDateFormat formatOUT = new SimpleDateFormat(listFormatOUT.get(cpt - 1).toString()); SimpleDateFormat formatIN = new SimpleDateFormat("yyyyMM"); String strPeriod = currentPeriod.toString().substring(0, 6); try { java.util.Date datePeriod = formatIN.parse(strPeriod); String dateString = formatOUT.format(datePeriod); tmp.replace(idx, idx + listFormatIN.get(cpt - 1).toString().length(), dateString); } catch (java.text.ParseException ex) { throw new BadFormatException(ex.getMessage()); } } else { throw new BadFormatException("Mauvais format d'instanciation du fichier"); } return new File(tmp.toString()); } /** * Determine la longueur de l'op�ration � effectuer (ex : Nb de lignes du fichier � * importer). La methode met a jour l'attribut lengthOfTask. * * @param ope Operation courante * * @exception Exception Description of Exception */ public void determineLengthOfTask(Operation ope) throws Exception { File file = determineInputFile(ope); LineNumberReader lnr = new LineNumberReader(new FileReader(file)); while (lnr.readLine() != null) {} setLengthOfTask(lnr.getLineNumber()); } /** * Retourne le fichier d'entr�e utilis� lorsque l'op�ration est automatique. * * @return - */ public File getAutoInputFile() { return new File(inBox, stdFileName); } /** * Retourne le commentaire. * * @return le commentaire. */ public String getCommentry() { return commentry; } /** * Gets the fieldImportList attribute of the ImportBehavior object * * @return The fieldImportList value */ public List getFieldImportList() { return fieldImportList; } /** * Retourne le separateur de champs. Cette information n'est utilise que pour les * imports a taille variable. * * @return Le separateur */ public String getFieldSeparator() { return fieldSeparator; } /** * Gets the FileType attribute of the ImportBehavior object * * @return The FileType value */ public String getFileType() { return fileType; } /** * Retourne inBox. * * @return inBox. */ public String getInBox() { return inBox; } /** * Retourne l'attribut de localisation du fichier. * * @return la localisation */ public String getLocation() { return location; } /** * Retourne outBox. * * @return outBox. */ public String getOutBox() { return outBox; } /** * Retourne la taille d'une ligne importe. * * @return La taille. */ public int getRecordLength() { return recordLength; } /** * Retourne le nom du fichier formatt� (ex : FICHIERmmaa.pen) * * @return la localisation */ public String getStdFileName() { return stdFileName; } /** * Retourne l'attribut de localisation du fichier * * @return la localisation */ public boolean isFixedLength() { return fixedLength; } /** * Retourne l'attribut fixedReadLine de ImportBehavior * * @return La valeur de fixedReadLine * * @see #setFixedReadLine() */ public boolean isFixedReadLine() { return fixedReadLine; } /** * Gets the HeaderLine attribute of the ImportBehavior object * * @return The HeaderLine value */ public boolean isHeaderLine() { return headerLine; } /** * Charge (si necessaire) tous les <code>FieldImport</code> necessaire a l'execution * de ce comportement. * * @exception PersistenceException * * @todo quand le passage de fieldImportList sera fait en Reference, il faudra la * parcourir pour la charger */ public void prepareProceed() throws PersistenceException {} /** * Lance l'import. * * <p> * Lecture du fichier d'entree ligne par ligne. * </p> * * @param ope - * * @exception Exception - * @throws IllegalArgumentException TODO */ public void proceed(Operation ope) throws Exception { if (ope == null) { throw new IllegalArgumentException("Op�ration invalide"); } if (fieldImportList.size() > getDestTable().getNumberOfCol()) { throw new IllegalArgumentException("Nb de FieldImport > Nb de colonnes"); } File inputFile = determineInputFile(ope); Connection con = getConnectionManager().getConnection(); try { doImport(con, inputFile, getDestTable().getDBTableName()); } finally { getConnectionManager().releaseConnection(con); } } /** * Positionne un filtre d'import. * * @param f La nouvelle valeur de filter */ public void setFilter(ImportFilter f) { filter = f; } /** * Positionne l'attribut fixedReadLine de ImportBehavior qui indique si la lecture * d'une ligne (pour le type fichier a longueur fixe) doit etre faites de maniere * fixe ou en tenant compte du retour chariot. * * @param newFixedReadLine La nouvelle valeur de fixedReadLine */ public void setFixedReadLine(boolean newFixedReadLine) { fixedReadLine = newFixedReadLine; } /** * Lance l'mport du fichier <code>inputFile</code>. * * @param con Description of the Parameter * @param inputFile Description of the Parameter * @param dbDestName Description of the Parameter * * @exception IOException Erreur de lecture du fichier * @exception SQLException Erreur d'acces BD * @exception InterruptedException Interruption utilisateur * @exception FieldNotFoundException Un champ est introuvable dans la ligne * @exception BadFormatException Un champ n'est pas au bon format */ protected void doImport(Connection con, File inputFile, String dbDestName) throws IOException, SQLException, InterruptedException, FieldNotFoundException, BadFormatException { testInputFile(inputFile); BufferedReader reader; if (isFixedLength() && isFixedReadLine()) { reader = new FixedReader(new FileReader(inputFile), getRecordLength()); } else { reader = new BufferedReader(new FileReader(inputFile)); } String line; setCurrentOfTask(0); PreparedStatement insertQuery = null; try { insertQuery = QueryHelper.buildInsertStatement(dbDestName, getDbFieldNameList(), con); if (headerLine == true) { reader.readLine(); incrementCurrentOfTask(); } while ((line = reader.readLine()) != null) { if (filter != null && filter.filteredLine(line)) { continue; } if (Thread.interrupted()) { throw new InterruptedException("Interruption utilisateur"); } incrementCurrentOfTask(); fillPreparedStatement(insertQuery, line); insertQuery.executeUpdate(); insertQuery.clearParameters(); } } finally { reader.close(); if (insertQuery != null) { insertQuery.close(); } } } /** * Ajoute un FieldImport � ImportBehavior. * * @param fieldImport Le FieldImport � ajouter * * @throws IllegalArgumentException TODO */ protected void addFieldImport(FieldImport fieldImport) { if (fieldImport == null) { throw new IllegalArgumentException(); } // UGLY : L'initialisation des champs FixedLength et Separator se font // ici, car ces informations sont stockee dans la table // PM_IMPORT. fieldImport.setFixedLength(fixedLength); fieldImport.setSeparator(fieldSeparator); if ((fieldImport.getFixedLength() == true) && ((fieldImport.getPosition() + fieldImport.getLength()) > recordLength)) { throw new IllegalArgumentException( "D�passement de la longueur d'enregistrement"); } fieldImportList.add(fieldImport); } /** * Description of the Method * * @param st Description of the Parameter * @param line Description of the Parameter * * @exception BadFormatException Description of the Exception * @exception FieldNotFoundException Description of the Exception * @exception SQLException Description of the Exception */ void fillPreparedStatement(PreparedStatement st, String line) throws BadFormatException, FieldNotFoundException, SQLException { Iterator iter = fieldImportList.iterator(); for (int pos = 1; iter.hasNext(); pos++) { FieldImport fi = (FieldImport)iter.next(); st.setObject(pos, fi.convertFieldToSQL(line), fi.getSQLType()); } } /** * Retourne l'attribut autoOutputFile de ImportBehavior * * @return La valeur de autoOutputFile */ File getAutoOutputFile() { return new File(outBox, stdFileName); } /** * Retourne l'attribut manuInputFile de ImportBehavior * * @return La valeur de manuInputFile */ File getManuInputFile() { return new File(location, stdFileName); } /** * Determine le fichier en entr�e. * * @param ope L'operation * * @return Le fichier d'entree * * @exception Exception Description of Exception */ private File determineInputFile(Operation ope) throws Exception { File inputFile; Period currentPeriod = ope.getPeriod(); if (ope.isAutomatic()) { inputFile = findRealFileName(getAutoInputFile(), currentPeriod); } else { inputFile = findRealFileName(getManuInputFile(), currentPeriod); } return inputFile; } /** * Retourne la liste des Noms de colonne. * * @return Liste de String. */ private List getDbFieldNameList() { List dbFieldNameList = new ArrayList(); Iterator iter = fieldImportList.iterator(); while (iter.hasNext()) { FieldImport fi = (FieldImport)iter.next(); dbFieldNameList.add(fi.getDBDestFieldName()); } return dbFieldNameList; } /** * Constructor for the init object * * @param fileType - * @param stdFileName - * @param location - * @param recordLength - * @param commentry - * @param outBox - * @param inBox - * @param fixedLength - * @param fieldSeparator - * @param headerLine - */ private void init(String fileType, String stdFileName, String location, int recordLength, String commentry, String outBox, String inBox, boolean fixedLength, String fieldSeparator, boolean headerLine) { this.fileType = fileType; this.stdFileName = stdFileName; this.location = location; this.recordLength = recordLength; this.commentry = commentry; this.outBox = outBox; this.inBox = inBox; this.fixedLength = fixedLength; this.fieldSeparator = fieldSeparator; this.headerLine = headerLine; } /** * Test la validite du fichier (ecrituer, etc.). * * @param inputFile Le fichier a tester * * @exception IOException Fichier non validep */ private void testInputFile(File inputFile) throws IOException { if (inputFile.exists() == false) { throw new IOException("Fichier introuvable : " + inputFile.getAbsoluteFile()); } if (inputFile.isFile() == false) { throw new IOException("Ce n'est pas un fichier : " + inputFile.getAbsoluteFile()); } if (inputFile.canRead() == false) { throw new IOException("Fichier illisible : " + inputFile.getAbsoluteFile()); } } }