001 package sears.file; 002 003 import java.io.File; 004 import java.util.ArrayList; 005 006 import sears.file.exception.io.FileConversionException; 007 import sears.gui.MainWindow; 008 import sears.tools.Utils; 009 010 /** 011 * Provides access method to file like <i>open</i> and <i>save</i> 012 * <br>An instance of this class captures error coming from the conversion of file to subtitle file 013 */ 014 public class FileSystemAccess { 015 016 private static FileSystemAccess instance; 017 private MainWindow mainWindow; 018 019 /** (<tt>int</tt>) maximum authorized size for a subtitle file, 2 Mo */ 020 public final static int MAX_SUBTITLE_FILE_SIZE = 2000000; 021 022 /** 023 * Gives the same instance of this class 024 * <br>Only used by <tt>MainWindow</tt> class 025 * @return an object instance of <tt>FileSystemAccess</tt> class. 026 */ 027 public static FileSystemAccess getInstance() { 028 if( instance == null ) { 029 instance = new FileSystemAccess(MainWindow.instance); 030 } 031 return instance; 032 } 033 034 /** 035 * Default constructor 036 * @param mainWindow the extended controller 037 */ 038 protected FileSystemAccess(MainWindow mainWindow) { 039 if( mainWindow == null ) { 040 throw new NullPointerException("main window cannot be null"); 041 } 042 this.mainWindow = mainWindow; 043 } 044 045 /** 046 * Tests the length of the <tt>java.io.File</tt> given in parameters 047 * @param file the file to test 048 * @throws FileConversionException if length or access to the file cause a problem 049 * @throws NullPointerException if <tt>file</tt> is null 050 */ 051 private void ensureFileLengthCoherence(File file) throws FileConversionException { 052 try { 053 if( file.length() >= MAX_SUBTITLE_FILE_SIZE ) { 054 throw FileConversionException.getAccessException( 055 FileConversionException.UNSUPPORTED_FILE_SIZE, file); 056 } 057 } catch( SecurityException e) { 058 throw FileConversionException.getAccessException( 059 FileConversionException.READ_ACCESS, file); 060 } 061 } 062 063 /** 064 * Provides a way to get a <tt>SubtitleFile</tt> instance from a file 065 * @param file the file to convert 066 * @param charset the charset used for the conversion 067 * @return the <tt>SubtitleFile</tt> object created or null if an error occurs 068 */ 069 public SubtitleFile openFile(File file, String charset) { 070 return openFile(file, null, charset); 071 } 072 073 private void fillArray(ArrayList<Subtitle> listToFill, ArrayList<Subtitle> savedList) { 074 listToFill.clear(); 075 listToFill.addAll(savedList); 076 } 077 078 /** 079 * Provides a way to get <tt>SubtitleFile</tt> instance from a file 080 * <br>If an error occurs an error dialog is called 081 * @param file the file to convert 082 * @param subtitleList the subtitle list to fill 083 * @param charset the charset used for the conversion 084 * @return the <tt>SubtitleFile</tt> object created or null if an error occurs 085 */ 086 public SubtitleFile openFile(File file, ArrayList<Subtitle> subtitleList, String charset) { 087 SubtitleFile subtitleFile = null; 088 // save the subtitle list in case of error: 089 ArrayList<Subtitle> savedSubtitleList = new ArrayList<Subtitle>(); 090 if( subtitleList == null ) { 091 // subtitleList becomes an empty array 092 subtitleList = savedSubtitleList; 093 } else { 094 savedSubtitleList.addAll(subtitleList); 095 subtitleList.clear(); 096 } 097 // Try to create the new subtitleFile: 098 try { 099 // ensure that the file length is not bigger than the one supported by Sears 100 ensureFileLengthCoherence(file); 101 // try to create a new Subtitle file 102 subtitleFile = SubtitleFile.getInstance(file, subtitleList, charset); 103 } catch ( FileConversionException e ) { 104 // 105 // file conversion error occurs: 106 // - malformed subtitle file 107 // - read access error 108 109 // return saved list 110 fillArray(subtitleList, savedSubtitleList); 111 charset = mainWindow.showOpenErrorDialog(e.getMessage(), e.getDetail(), e.couldBeABadEncoding()); 112 if( charset != null ) { 113 mainWindow.openFile(file, charset); 114 } // else, error dialog has be closed by user, do not try to reopen file 115 } catch ( NullPointerException e) { 116 // 117 // DEVELOPER: 118 // one of the parameters is null !! 119 120 // return saved list 121 fillArray(subtitleList, savedSubtitleList); 122 e.printStackTrace(); 123 mainWindow.showOpenErrorDialog("unknow error", e.toString(), false); 124 125 } catch ( Exception e ) { 126 // 127 // DEVELOPER: 128 // if an unknown error occurs, a generic dialog is show... 129 130 // return saved list 131 fillArray(subtitleList, savedSubtitleList); 132 e.printStackTrace(); 133 mainWindow.showOpenErrorDialog("unknow error",e.toString(), false); 134 } 135 return subtitleFile; 136 } 137 138 /** 139 * Writes the subtitle to a file and invokes an error dialog if an error occurs during the action 140 * @param file the file in which the subtitle must be write 141 * @param subtitleFile the subtitle to write 142 * @param charset the charset used to write the file, if null the subtitle's charset will be used 143 * @return true if action succeed, false if not 144 */ 145 public boolean saveFile(File file, SubtitleFile subtitleFile, String charset) { 146 boolean isFileSaved = false; 147 if (subtitleFile != null) { 148 if( charset != null ) { 149 subtitleFile.setCharset(charset); 150 } // else the file will be saved with this defined charset 151 try { 152 //we have to check wether we are saving into the same format 153 if(subtitleFile.getFile().getName().endsWith(Utils.getExtension(file))){ 154 //If same extension, save the file 155 subtitleFile.writeToFile(file); 156 }else{ 157 //If not the same extension, create the new subtitle file., using the empty constructor of getInstance facility (true) 158 SubtitleFile newFile = SubtitleFile.getInstance(file, null, null, true); 159 //File has not been set by empty constructor, set it 160 newFile.setFile(file); 161 //copy subtitle list 162 newFile.setSubtitleList(subtitleFile.getSubtitleList()); 163 //And save the new file 164 newFile.writeToFile(file); 165 } 166 isFileSaved = true; 167 } catch (FileConversionException e) { 168 mainWindow.showSaveErrorDialog(e.getMessage(), e.getDetail()); 169 } catch (Exception e) { 170 mainWindow.showSaveErrorDialog(e.getMessage(),e.getLocalizedMessage()); 171 } 172 } 173 return isFileSaved; 174 } 175 }