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