001 package sears.file.exception.io; 002 003 import java.io.File; 004 import java.io.IOException; 005 006 import sears.file.FileSystemAccess; 007 import sears.tools.Utils; 008 009 /** 010 * A <tt>FileConversionException</tt> is throw when an error occurs during a file access 011 * and conversion to subtitle file 012 * <br>This class provides <tt>static</tt> methods to create generic objects using 013 * the class constants. 014 * <p> 015 * Two distinct categories of constants: 016 * <br>- file access exception ( read and write access ) 017 * <br>- malformed subtitle file exception 018 * </p> 019 */ 020 public abstract class FileConversionException extends IOException { 021 022 // FILE ACCESS EXCEPTION : 023 // +++++++++++++++++++++ 024 // 025 /** FILE ACCESS EXCEPTION: Read access exception */ 026 public static final int READ_ACCESS = 0; 027 /** FILE ACCESS EXCEPTION: Write access exception */ 028 public static final int WRITE_ACCESS = 1; 029 /** FILE ACCESS EXCEPTION: unsupported file size exception */ 030 public static final int UNSUPPORTED_FILE_SIZE = 2; 031 032 // MALFORMED SUBTITLE FILE EXCEPTION : 033 // +++++++++++++++++++++++++++++++++ 034 // 035 // + NUMBER - MALFORMED SUBTITLE FILE EXCEPTION 036 /** MALFORMED SUBTITLE FILE EXCEPTION: no subtitle number exception */ 037 public static final int NO_SUBTITLE_NUMBER = 3; 038 /** MALFORMED SUBTITLE FILE EXCEPTION: malformed subtitle number exception */ 039 public static final int MALFORMED_SUBTITLE_NUMBER = 4; 040 041 // + TIME - MALFORMED SUBTITLE FILE EXCEPTION 042 /** MALFORMED SUBTITLE FILE EXCEPTION: no subtitle time exception */ 043 public static final int NO_SUBTITLE_TIME = 5; 044 /** MALFORMED SUBTITLE FILE EXCEPTION: malformed subtitle time line exception */ 045 public static final int MALFORMED_TIME_LINE = 6; 046 /** MALFORMED SUBTITLE FILE EXCEPTION: malformed subtitle start time exception */ 047 public static final int MALFORMED_START_TIME = 7; 048 /** MALFORMED SUBTITLE FILE EXCEPTION: malformed subtitle end time exception */ 049 public static final int MALFORMED_END_TIME = 8; 050 051 // + TEXT - MALFORMED SUBTITLE FILE EXCEPTION 052 /** MALFORMED SUBTITLE FILE EXCEPTION: no subtitle text exception */ 053 public static final int NO_SUBTITLE_TEXT = 9; 054 /** MALFORMED SUBTITLE FILE EXCEPTION: malformed subtitle text exception */ 055 public static final int MALFORMED_SUBTITLE_TEXT = 10; 056 057 // + GENERIC MALFORMED SUBTITLE FILE EXCEPTION 058 /** MALFORMED SUBTITLE FILE EXCEPTION: generic subtitle file exception */ 059 public static final int MALFORMED_SUBTITLE_FILE = 11; 060 061 // + SPECIAL MALFORMED SUBTITLE FILE EXCEPTION 062 /** MALFORMED SUBTITLE FILE EXCEPTION: unexpected end of file exception */ 063 public static final int UNEXPECTED_END_OF_FILE = 12; 064 /** MALFORMED SUBTITLE FILE EXCEPTION: empty subtitle file exception */ 065 public static final int EMPTY_SUBTITLE_FILE = 13; 066 067 /** 068 * Returns the error message 069 * @return the error message 070 */ 071 public abstract String getMessage(); 072 073 /** 074 * Returns the detail error message 075 * @return the detail error message 076 */ 077 public abstract String getDetail(); 078 079 /** 080 * Returns a <tt>boolean</tt> which indicates if the error could have 081 * appeared because of a bad encoding/decoding 082 * @return true if the error could be appear because a bad encoding/decoding 083 * false if not 084 */ 085 public abstract boolean couldBeABadEncoding(); 086 087 // returns a formatted message by analyze <tt>file</tt> parameter 088 private static String fileDetail(File file) { 089 String detail = ""; 090 try { 091 detail = file.getPath() + Utils.LINE_SEPARATOR; 092 } catch( NullPointerException e ) { 093 detail = ""; 094 } 095 return detail; 096 } 097 098 // READ ERROR 099 // returns a formatted error message by testing <tt>file</tt> parameter 100 private static String iOExceptionDetailWhenReading(File file) { 101 String message = null; 102 if( file != null ) { 103 try { 104 if( file.exists() ) { 105 if( !file.canRead() ) { 106 message = "File read access is denied"; 107 } else { 108 message = "Unknow error, the file seems to be readable"; 109 } 110 } else { 111 message = "File does not exist"; 112 } 113 } catch (SecurityException e) { 114 message = "There's a security restriction on this file"; 115 } 116 } else { 117 message = "Unknow error"; 118 } 119 return message; 120 } 121 122 // WRITE ERROR 123 // returns a formatted error message by testing <tt>file</tt> parameter 124 private static String iOExceptionDetailWhenWriting(File file) { 125 String message = null; 126 if( file != null ) { 127 try { 128 if( file.exists() ) { 129 if( !file.canWrite() ) { 130 message = "File write access is denied"; 131 } else { 132 message = "Unknow error, the file seems to be writable"; 133 } 134 } else { 135 message = "File does not exist"; 136 } 137 } catch (SecurityException e) { 138 message = "There's a security restriction on this file"; 139 } 140 } else { 141 message = "Unknow error"; 142 } 143 return message; 144 } 145 146 // LENGTH ERROR 147 // returns a formatted error message by testing <tt>file</tt> parameter 148 private static String getFileLengthMessage(File file) { 149 String message = ""; 150 try { 151 message = file.length() + " octets is too big" 152 + Utils.LINE_SEPARATOR 153 + "SEARS do not support file bigger than " 154 + FileSystemAccess.MAX_SUBTITLE_FILE_SIZE + " octets"; 155 } catch (SecurityException e) { 156 message = "SEARS do not support file bigger than " 157 + FileSystemAccess.MAX_SUBTITLE_FILE_SIZE + " octets"; 158 } catch (NullPointerException e) { 159 // DEVELOPPER: 160 // ???? 161 // file is null !!!! 162 message = "Unknow error"; 163 } 164 return message; 165 } 166 167 /** 168 * Get a new <tt>FileConversionException</tt> instance 169 * @param type <tt>READ_ACCESS</tt>, <tt>WRITE_ACCESS</tt>, <tt>UNSUPPORTED_FILE_SIZE</tt> 170 * @param file the file where the error is encountered 171 * @return a new read access exception 172 */ 173 public static FileConversionException getAccessException(int type, File file) { 174 String message = ""; 175 String detail = ""; 176 switch ( type ) { 177 case READ_ACCESS: 178 message = "Read access error"; 179 detail = fileDetail(file) + iOExceptionDetailWhenReading(file) + ", " 180 + Utils.LINE_SEPARATOR + "please checks your authorisation on this file"; 181 break; 182 case WRITE_ACCESS: 183 message = "Write access error"; 184 detail = fileDetail(file) + iOExceptionDetailWhenWriting(file) + ", " 185 + Utils.LINE_SEPARATOR + "please checks your authorisation on this file"; 186 break; 187 case UNSUPPORTED_FILE_SIZE: 188 message = "Unsupported file size"; 189 detail = fileDetail(file) + getFileLengthMessage(file); 190 break; 191 default: 192 throw new IllegalArgumentException(type + " is not a valid identifier for an exception type"); 193 } 194 return new Bean(message, detail, false); 195 } 196 197 /** 198 * Get a new <tt>FileConversionException</tt> instance 199 * @param type <tt>UNEXPECTED_END_OF_FILE</tt>, <tt>EMPTY_SUBTITLE_FILE</tt> 200 * @param file the file on which the error occurs 201 * @return a new malformed subtitle file exception 202 */ 203 public static FileConversionException getMalformedSubtitleFileException(int type, File file) { 204 String message = ""; 205 String detail = ""; 206 switch ( type ) { 207 case UNEXPECTED_END_OF_FILE: 208 message = "Subtitle file seems to be corrupted"; 209 detail = fileDetail(file) + "unexpected end of file"; 210 break; 211 case EMPTY_SUBTITLE_FILE: 212 message = "file is empty"; 213 detail = fileDetail(file) + "Sears can't read empty subtitle file"; 214 break; 215 default: 216 throw new IllegalArgumentException(type + " is not a valid identifier for an exception type"); 217 } 218 return new Bean(message, detail, false); 219 } 220 221 /** 222 * Get a new <tt>FileConversionException</tt> instance 223 * @param type <tt>MALFORMED_SUBTITLE_NUMBER <br>NO_SUBTITLE_TIME 224 * <br>MALFORMED_TIME_LINE<br>MALFORMED_START_TIME 225 * <br>MALFORMED_END_TIME<br>NO_SUBTITLE_TEXT 226 * <br>MALFORMED_SUBTITLE_TEXT<br>MALFORMED_SUBTITLE_FILE</tt> 227 * @param file the file on which the error occurrs 228 * @param lineNumber the line number where the error is encountered 229 * @param line the line where the error is encountered 230 * @return a new <tt>FileConversionException</tt> instance 231 */ 232 public static FileConversionException getMalformedSubtitleFileException(int type, File file, int lineNumber, String line) { 233 String message = "Subtitle file seems to be corrupted"; 234 String detail = ""; 235 switch ( type ) { 236 case NO_SUBTITLE_NUMBER: 237 detail = fileDetail(file) 238 + "no subtitle number at line " + lineNumber; 239 break; 240 case MALFORMED_SUBTITLE_NUMBER: 241 detail = fileDetail(file) 242 + "no subtitle number at line " + lineNumber 243 + Utils.LINE_SEPARATOR + line; 244 break; 245 case NO_SUBTITLE_TIME: 246 detail = fileDetail(file) 247 + "no time at line " + lineNumber; 248 break; 249 case MALFORMED_TIME_LINE: 250 detail = fileDetail(file) 251 + "malformed time at line " + lineNumber 252 + Utils.LINE_SEPARATOR + line; 253 break; 254 case MALFORMED_START_TIME: 255 detail = fileDetail(file) 256 + "malformed start time at line " + lineNumber 257 + Utils.LINE_SEPARATOR + line; 258 break; 259 case MALFORMED_END_TIME: 260 detail = fileDetail(file) 261 + "malformed end time at line " + lineNumber 262 + Utils.LINE_SEPARATOR + line; 263 break; 264 case NO_SUBTITLE_TEXT: 265 detail = fileDetail(file) 266 + "no subtitle text at line " + lineNumber; 267 break; 268 case MALFORMED_SUBTITLE_TEXT: 269 detail = fileDetail(file) 270 + "no subtitle text at line " + lineNumber; 271 break; 272 case MALFORMED_SUBTITLE_FILE: 273 detail = fileDetail(file) 274 + "unknow error " + Utils.LINE_SEPARATOR 275 + "malformed subtitle file at line " + lineNumber; 276 break; 277 default: 278 throw new IllegalArgumentException(type + " is not a valid identifier for an exception type"); 279 } 280 return new Bean(message, detail, true); 281 } 282 283 /** 284 * Get a new <tt>FileConversionException</tt> instance 285 * @param file the file in cause 286 * @param extension the <tt>file</tt> extension 287 * @return a unsupported file format exception 288 */ 289 public static FileConversionException getUnsupportedFileFormatException(File file, String extension) { 290 return new Bean( 291 // MESSAGE 292 "unsupported file format", 293 // DETAIL 294 fileDetail(file) 295 + extension + " file is not supported by Sears", 296 // COULD BE THE RESULT OF A BAD ENCODING 297 false 298 ); 299 } 300 } 301 302 /** 303 * This class provides a way to create a basic FileConversion object 304 * <br> Used by the <tt>static</tt> methods of the abstract class that <tt>Bean</tt> extends 305 */ 306 class Bean extends FileConversionException { 307 308 private static final long serialVersionUID = 75866932870197914L; 309 310 private String message; 311 private String detail; 312 private Boolean couldBeABadEncoding; 313 314 /** 315 * Constructs a new object with an error message, 316 * detail for this error and a <tt>boolean</tt> 317 * to know if the error could be occur because a bad encoding/decoding 318 * @param message the error message 319 * @param detail the detail of the error 320 * @param couldBeABadEncoding if the error may cause by a bad decoding/encoding value is true, false if not 321 */ 322 public Bean(String message, String detail, boolean couldBeABadEncoding) { 323 this.message = message; 324 this.detail = detail; 325 this.couldBeABadEncoding = couldBeABadEncoding; 326 } 327 328 /* 329 * (non-Javadoc) 330 * @see sears.file.exception.io.FileConversionException#couldBeABadEncoding() 331 */ 332 public boolean couldBeABadEncoding() { 333 return couldBeABadEncoding; 334 } 335 336 /* 337 * (non-Javadoc) 338 * @see sears.file.exception.io.FileConversionException#getDetail() 339 */ 340 public String getDetail() { 341 return detail; 342 } 343 344 /* 345 * (non-Javadoc) 346 * @see sears.file.exception.io.FileConversionException#getMessage() 347 */ 348 public String getMessage() { 349 return message; 350 } 351 }