DBImportFileCoder.java

00001 /*
00002  * OpenMobileIS - a free Java(TM) Framework for mobile applications Java(TM)
00003  * Copyright (C) 2004-2006 Philippe Delrieu
00004  * All rights reserved.
00005  * Contact: pdelrieu@openmobileis.org
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00020  * USA
00021  *
00022  *  Author : Philippe Delrieu
00023  * 
00024  */
00025 
00026 package org.openmobileis.synchro.openmsp.client.db;
00027 
00028 import java.io.*;
00029 
00030 import org.openmobileis.common.util.PropertiesManager;
00031 import org.openmobileis.common.util.codec.GeneralCoder;
00032 import org.openmobileis.common.util.collection.Array;
00033 import org.openmobileis.synchro.openmsp.OpenMSPException;
00034 
00042 public final class DBImportFileCoder {
00043   public static final char ADDAction ='A';
00044   public static final char REPLACEAction= 'R';
00045   public static final char DELETEAction= 'D';
00046   public static final char endLine = '\n';
00047   public static final char dataSeparator = ';';
00048   public static final char stringSeparator = '\'';
00049         public static final char antislashSeparator = '\\';
00050         public char guillemetannulator = '\\';
00051         private static DBImportFileCoder coder;
00052         
00053         private DBImportFileCoder()     {
00054                 String newGuillemetAnnulator = PropertiesManager.getManager().getProperty("server.common.util.string.format.sql.guillement");
00055                 if (newGuillemetAnnulator != null)      {
00056                         guillemetannulator = newGuillemetAnnulator.charAt(0);
00057                 }
00058         }
00059         
00060         public static DBImportFileCoder getCoder()      {
00061                 if (coder==null)        {
00062                         synchronized(DBImportFileCoder.class)   {
00063                                 if (coder == null)      {
00064                                         coder = new DBImportFileCoder();
00065                                 }
00066                         }
00067                 }
00068                 return coder;
00069         }
00070 
00075   public char[] encodeData(char action, String[] rowData) throws OpenMSPException {
00076     CharArrayWriter writer = new CharArrayWriter();
00077     try {
00078       writer.write(action);
00079       writer.write(dataSeparator);
00080       for (int i=0; i<rowData.length; i++) {
00081         if (rowData[i] == null) {
00082           writer.write("NULL");
00083         } else  {
00084           writer.write(rowData[i]);
00085         }
00086         if (i!=rowData.length -1)  {
00087           writer.write(dataSeparator);
00088         }
00089       }
00090       writer.write(endLine);
00091     } catch (Exception ex)  {
00092       throw new OpenMSPException("DBImportFileCoder encodeData Error ", ex);
00093     } finally {
00094       writer.flush();
00095       writer.close();
00096     }
00097     return writer.toCharArray();
00098   }
00099 
00100   public String formateString(String data) {
00101     StringBuffer str = new StringBuffer(stringSeparator);
00102     str.append(data).append(stringSeparator);
00103     return str.toString();
00104   }
00105 
00106   public String removeAntiSlash(String input)  {
00107     char[] chs = input.toCharArray();
00108     int size = chs.length;
00109     CharArrayWriter out = new CharArrayWriter(30);
00110     for (int i=0; i < size; i++)  {
00111       if (chs[i] == antislashSeparator) {
00112         continue;
00113       }
00114       out.write(chs[i]);
00115     }
00116     out.flush();
00117     out.close();
00118     return out.toString();
00119   }
00120 
00121 
00125   public void decodeFileData(String filename, DecodedRowListener listener) throws OpenMSPException {
00126     try {
00127       BufferedReader reader = new BufferedReader(new FileReader(filename));
00128       try {
00129         char read = 0;
00130         int input = 0;
00131         boolean insideString = false;
00132         StringBuffer str = new StringBuffer();
00133         Array dataList = new Array(10);
00134         boolean seeStringSeparator = false;
00135         boolean seeAntiSeparator = false;
00136         int line =0;
00137         char action =0;
00138         boolean rowBeginned = false;
00139         while ((input = reader.read()) != -1) {
00140           read=(char) input;
00141           if (!insideString)  {
00142             if (read == dataSeparator)  {
00143               if (rowBeginned)  {
00144                 String toAdd = str.toString();
00145                 if (toAdd.equals("NULL"))  {
00146                   dataList.add(null);
00147                 } else  {
00148                   dataList.add(toAdd);
00149                 }
00150                 str.setLength(0);
00151               } else  {
00152                 action = str.charAt(0);
00153                 rowBeginned = true;
00154                 str.setLength(0);
00155               }
00156               continue;
00157             } else if (read == stringSeparator)  {
00158               insideString = true;
00159               seeStringSeparator = false;
00160               seeAntiSeparator = false;
00161               continue;
00162             } else if (read == endLine) {
00163               line++;
00164               String toAdd = str.toString();
00165               if (toAdd.equals("NULL"))  {
00166                 dataList.add(null);
00167               } else  {
00168                 dataList.add(toAdd);
00169               }
00170               str.setLength(0);
00171               // notify row.
00172               String[] rowData = new String[dataList.size()];
00173               dataList.toArray(rowData);
00174               listener.notifyNewRowDecoded(action, rowData);
00175               dataList.clear();
00176               rowBeginned = false;
00177               continue;
00178             }
00179           } else  {
00180             if (read == antislashSeparator)  {
00181                 seeAntiSeparator = true;
00182             } else if (read == stringSeparator)  {
00183               if (seeAntiSeparator) {
00184                 seeAntiSeparator = false;
00185               } else  {
00186                 seeStringSeparator = true;
00187                 continue;
00188               }
00189             } else if (seeStringSeparator) {
00190               insideString = false;
00191               if (read == dataSeparator)  {
00192                 dataList.add(str.toString());
00193                 str.setLength(0);
00194               } else if (read == endLine) {
00195                 line++;
00196                 dataList.add(str.toString());
00197                 str.setLength(0);
00198                 // notify row.
00199                 String[] rowData = new String[dataList.size()];
00200                 dataList.toArray(rowData);
00201                 listener.notifyNewRowDecoded(action, rowData);
00202                 dataList.clear();
00203                 rowBeginned = false;
00204                 continue;
00205               } else  {
00206                 listener.notifyError(line, read);
00207               }
00208               continue;
00209             } else  if (seeAntiSeparator){
00210               seeAntiSeparator = false;
00211             }
00212           }
00213           str.append(read);
00214         }
00215       } finally {
00216         reader.close();
00217       }
00218     } catch (Exception ex) {
00219       throw new OpenMSPException("DBImportFileCoder decodeFileData Error ", ex);
00220     }
00221   }
00222 
00223   public String cleanAndFormatStringforDB(String toFormat)  {
00224     if (toFormat == null)
00225       return "NULL";
00226     return new String(cleanAndFormatStringforDB(toFormat.toCharArray()));
00227   }
00228 
00229   private char[] cleanAndFormatStringforDB(char[] toFormat)  {
00230         
00231     CharArrayWriter writer  = new CharArrayWriter();
00232     for (int i=0; i<toFormat.length; i++) {
00233                         if (toFormat[i] == '\'')  {
00234                                 writer.write(guillemetannulator);
00235                         } else if (toFormat[i] == antislashSeparator)  {
00236                                 writer.write(antislashSeparator);
00237                         } else if (toFormat[i] == 0)  {
00238                                 writer.write(' ');
00239                                 continue; //skip caractere 00
00240       }
00241       writer.write(toFormat[i]);
00242     }
00243     writer.flush();
00244     writer.close();
00245     return writer.toCharArray();
00246   }
00247   
00248   public String truncateSqlString(String str, int trunc)        {
00249         if (trunc <= str.length()){
00250                 while (trunc >=0 && (str.charAt(trunc) == guillemetannulator || str.charAt(trunc) == '\''))     {
00251                         trunc --;
00252                 }
00253                 return str.substring(0, trunc);
00254         }
00255         return str;
00256   }
00257   
00258   public String decodeString(String inputString) {
00259     if (inputString == null) {
00260       return ("NULL");
00261     }
00262     return DBImportFileCoder.getCoder().removeAntiSlash(inputString);
00263   }
00264 
00265   public String encodeInString(String inputString)  {
00266     if (inputString == null) {
00267       return ("NULL");
00268     }
00269     char[] toEncode = cleanAndFormatStringforDB(inputString.toCharArray());
00270     char[] encoded = new char[toEncode.length+2];
00271     encoded[0] = '\'';
00272     encoded[toEncode.length+1] = '\'';
00273     System.arraycopy(toEncode, 0, encoded, 1, toEncode.length);
00274     return new String(encoded);
00275   }
00276 
00282   public String[] decodeData(String data)  {
00283     char read = 0;
00284     boolean insideString = false;
00285     StringBuffer str = new StringBuffer();
00286     Array dataList = new Array(10);
00287     boolean seeStringSeparator = false;
00288     boolean seeAntiSeparator = false;
00289     for (int i=2; i<data.length(); i++) { // begin after the action
00290       read=data.charAt(i);
00291       if (!insideString)  {
00292         if (read == dataSeparator)  {
00293           String toAdd = str.toString();
00294           if (toAdd.equals("NULL"))  {
00295             dataList.add(null);
00296           } else  {
00297             dataList.add(toAdd);
00298           }
00299           str.setLength(0);
00300           continue;
00301         } else if (read == stringSeparator)  {
00302           insideString = true;
00303           seeStringSeparator = false;
00304           seeAntiSeparator = false;
00305           continue;
00306         } else if (read == endLine) {
00307           break;
00308         }
00309       } else  {
00310         if (read == antislashSeparator)  {
00311           seeAntiSeparator = true;
00312         } else if (read == stringSeparator)  {
00313           if (seeAntiSeparator) {
00314             seeAntiSeparator = false;
00315           } else  {
00316             seeStringSeparator = true;
00317             continue;
00318           }
00319         } else if (seeStringSeparator) {
00320           insideString = false;
00321           if (read == dataSeparator)  {
00322             dataList.add(str.toString());
00323             str.setLength(0);
00324           } else if (read == endLine) {
00325             break;
00326           } else  {
00327             return null;
00328           }
00329           continue;
00330         } else  if (seeAntiSeparator){
00331           seeAntiSeparator = false;
00332         }
00333       }
00334       str.append(read);
00335     }
00336     
00337 
00338     // add the current buffer
00339     String toAdd = str.toString();
00340     if (toAdd.equals("NULL"))  {
00341       dataList.add(null);
00342     } else  {
00343       dataList.add(toAdd);
00344     }
00345     String[] rowData = new String[dataList.size()];
00346     dataList.toArray(rowData);
00347     return rowData;
00348   }
00349   
00350   public String convertBooleanToDBData(boolean bool)    {
00351         if (bool) return "1";
00352         return "0";
00353   }
00354   
00355   public boolean convertDBDataToBoolean(byte data)      {
00356         if (data == 0) return false;
00357         return true;
00358   }
00359 
00360   public String[] serializeDBObject (String uid, Object obj) throws IOException {
00361     String[] data = new String[2];
00362     data[0] = uid;
00363     ByteArrayOutputStream bstr = new ByteArrayOutputStream();
00364     ObjectOutputStream ostr = new ObjectOutputStream(bstr);
00365     ostr.writeObject(obj);
00366     byte[] b = bstr.toByteArray();
00367     data[1] = new String(GeneralCoder.encodeBase64(b));
00368     return data;
00369   }
00370   
00371   public Object unserializeDBObject(String[] synchroData) throws IOException, ClassNotFoundException {
00372       ByteArrayInputStream bstr = new ByteArrayInputStream(GeneralCoder.decodeBase64(synchroData[1].getBytes()));
00373       ObjectInputStream ostr = new ObjectInputStream(bstr);
00374       return ostr.readObject();
00375   }
00376 
00377   public static void main(String[] args) {
00378     try {
00379             DecodedRowListener listener = new DecodedRowListener()  {
00380               public void notifyNewRowDecoded(char action, String[] rowData) throws OpenMSPException {
00381                 String str = new String(DBImportFileCoder.getCoder().encodeData(action, rowData));
00382                 System.out.println("Decoded row :"+str);
00383               }
00384         
00385               public void notifyError(int ligne, char errorCharacter) {
00386                 System.out.println("Error found line "+ligne+" char "+errorCharacter);
00387               }
00388             };
00389         
00390             String[] addData = {"1234", "'first String'", "'test inside \\'\\'inside\\'\\' fin'", "345"};
00391             String[] deleteData = {"'second  String line end \\n suite \\n'", "23", "'test inside \\'\\'inside\\'\\''"};
00392             String[] updateData = {"'thrid  separator ;;\\'\\';\\'\\''","'String'","''",null, "345"};
00393         
00394             System.out.println("try file encoding");
00395             try {
00396               FileWriter writer = new FileWriter("/home/pdelrieu/dev/temp/testimportfile.txt");
00397               char[] endoded = DBImportFileCoder.getCoder().encodeData(DBImportFileCoder.ADDAction, addData);
00398               System.out.println("Endoded :"+new String(endoded));
00399               writer.write(endoded);
00400         
00401               endoded = DBImportFileCoder.getCoder().encodeData(DBImportFileCoder.DELETEAction, deleteData);
00402               System.out.println("Endoded :"+new String(endoded));
00403               writer.write(endoded);
00404         
00405               endoded = DBImportFileCoder.getCoder().encodeData(DBImportFileCoder.REPLACEAction, updateData);
00406               System.out.println("Endoded :"+new String(endoded));
00407               writer.write(endoded);
00408         
00409               writer.flush();
00410               writer.close();
00411         
00412               DBImportFileCoder.getCoder().decodeFileData("/home/pdelrieu/dev/temp/testimportfile.txt", listener);
00413             } catch (Exception ex)  {
00414               ex.printStackTrace();
00415             }
00416         
00417             String encoded = new String(DBImportFileCoder.getCoder().encodeData(DBImportFileCoder.ADDAction, addData));
00418             String[] data = DBImportFileCoder.getCoder().decodeData(encoded);
00419             StringBuffer buff = new StringBuffer("Decoded Data :");
00420             for (int i=0; i<data.length; i++) {
00421               buff.append('#').append(data[i]);
00422             }
00423             System.out.println(buff.toString());
00424         
00425             encoded = new String(DBImportFileCoder.getCoder().encodeData(DBImportFileCoder.DELETEAction, deleteData));
00426             data = DBImportFileCoder.getCoder().decodeData(encoded);
00427             buff = new StringBuffer("Decoded Data :");
00428             for (int i=0; i<data.length; i++) {
00429               buff.append('#').append(data[i]);
00430             }
00431             System.out.println(buff.toString());
00432         
00433         
00434             encoded = new String(DBImportFileCoder.getCoder().encodeData(DBImportFileCoder.REPLACEAction, updateData));
00435             data = DBImportFileCoder.getCoder().decodeData(encoded);
00436             buff = new StringBuffer("Decoded Data :");
00437             for (int i=0; i<data.length; i++) {
00438               buff.append('#').append(data[i]);
00439             }
00440             System.out.println(buff.toString());
00441     } catch (Exception ex)      {
00442       ex.printStackTrace();
00443     }
00444 
00445 
00446   }
00447 }

Generated on Mon Jan 11 21:19:13 2010 for OpenMobileIS by  doxygen 1.5.4