001 package com.croftsoft.core.io; 002 003 import java.applet.*; 004 import java.io.*; 005 import java.util.zip.*; 006 007 import com.croftsoft.core.applet.AppletLib; 008 import com.croftsoft.core.jnlp.JnlpLib; 009 import com.croftsoft.core.lang.NullArgumentException; 010 import com.croftsoft.core.lang.Testable; 011 012 /********************************************************************* 013 * Saves and loads Serializable objects using GZIP compression. 014 * 015 * @version 016 * 2003-06-13 017 * @since 018 * 2001-04-25 019 * @author 020 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 021 *********************************************************************/ 022 023 public final class SerializableLib 024 ////////////////////////////////////////////////////////////////////// 025 ////////////////////////////////////////////////////////////////////// 026 { 027 028 private static final String PROPERTY_USER_HOME = "user.home"; 029 030 ////////////////////////////////////////////////////////////////////// 031 // test methods 032 ////////////////////////////////////////////////////////////////////// 033 034 /********************************************************************* 035 * Displays the result of test(). 036 *********************************************************************/ 037 public static void main ( String [ ] args ) 038 throws Exception 039 ////////////////////////////////////////////////////////////////////// 040 { 041 System.out.println ( test ( args ) ); 042 } 043 044 public static boolean test ( String [ ] args ) 045 ////////////////////////////////////////////////////////////////////// 046 { 047 try 048 { 049 final String TEST = "CroftSoft"; 050 051 if ( !TEST.equals ( 052 load ( new ByteArrayInputStream ( compress ( TEST ) ) ) ) ) 053 { 054 return false; 055 } 056 057 String testCopy = ( String ) copy ( TEST ); 058 059 if ( ( testCopy == TEST ) 060 || !testCopy.equals ( TEST ) ) 061 { 062 return false; 063 } 064 } 065 catch ( Exception ex ) 066 { 067 ex.printStackTrace ( ); 068 069 return false; 070 } 071 072 return true; 073 } 074 075 ////////////////////////////////////////////////////////////////////// 076 ////////////////////////////////////////////////////////////////////// 077 078 public static byte [ ] compress ( Serializable serializable ) 079 throws IOException 080 ////////////////////////////////////////////////////////////////////// 081 { 082 NullArgumentException.check ( serializable ); 083 084 ByteArrayOutputStream byteArrayOutputStream 085 = new ByteArrayOutputStream ( ); 086 087 save ( serializable, byteArrayOutputStream ); 088 089 return byteArrayOutputStream.toByteArray ( ); 090 } 091 092 public static Serializable copy ( Serializable serializable ) 093 throws IOException 094 ////////////////////////////////////////////////////////////////////// 095 { 096 ByteArrayOutputStream byteArrayOutputStream 097 = new ByteArrayOutputStream ( ); 098 099 ObjectOutputStream objectOutputStream 100 = new ObjectOutputStream ( byteArrayOutputStream ); 101 102 objectOutputStream.writeObject ( serializable ); 103 104 byte [ ] bytes = byteArrayOutputStream.toByteArray ( ); 105 106 ByteArrayInputStream byteArrayInputStream 107 = new ByteArrayInputStream ( bytes ); 108 109 ObjectInputStream objectInputStream 110 = new ObjectInputStream ( byteArrayInputStream ); 111 112 try 113 { 114 return ( Serializable ) objectInputStream.readObject ( ); 115 } 116 catch ( ClassNotFoundException ex ) 117 { 118 // This should never happen since the same classes are used. 119 120 throw new RuntimeException ( ); 121 } 122 } 123 124 ////////////////////////////////////////////////////////////////////// 125 // load methods 126 ////////////////////////////////////////////////////////////////////// 127 128 public static Serializable load ( InputStream inputStream ) 129 throws ClassNotFoundException, IOException 130 ////////////////////////////////////////////////////////////////////// 131 { 132 NullArgumentException.check ( inputStream ); 133 134 ObjectInputStream objectInputStream = null; 135 136 try 137 { 138 objectInputStream 139 = new ObjectInputStream ( 140 new GZIPInputStream ( 141 new BufferedInputStream ( inputStream ) ) ); 142 143 return ( Serializable ) objectInputStream.readObject ( ); 144 } 145 finally 146 { 147 if ( objectInputStream != null ) 148 { 149 objectInputStream.close ( ); 150 } 151 else 152 { 153 inputStream.close ( ); 154 } 155 } 156 } 157 158 public static Serializable load ( String filename ) 159 throws ClassNotFoundException, IOException 160 ////////////////////////////////////////////////////////////////////// 161 { 162 NullArgumentException.check ( filename ); 163 164 return load ( new FileInputStream ( filename ) ); 165 } 166 167 public static Serializable load ( 168 String primaryFilename, 169 String fallbackFilename ) 170 throws ClassNotFoundException, IOException 171 ////////////////////////////////////////////////////////////////////// 172 { 173 NullArgumentException.check ( primaryFilename ); 174 175 if ( fallbackFilename == null ) 176 { 177 return load ( primaryFilename ); 178 } 179 180 try 181 { 182 return load ( primaryFilename ); 183 } 184 catch ( FileNotFoundException ex ) 185 { 186 } 187 catch ( Exception ex ) 188 { 189 ex.printStackTrace ( ); 190 } 191 192 return load ( fallbackFilename ); 193 } 194 195 public static Serializable load ( 196 ClassLoader classLoader, 197 String filename ) 198 throws ClassNotFoundException, IOException 199 ////////////////////////////////////////////////////////////////////// 200 { 201 NullArgumentException.check ( classLoader ); 202 203 NullArgumentException.check ( filename ); 204 205 InputStream inputStream 206 = classLoader.getResourceAsStream ( filename ); 207 208 if ( inputStream == null ) 209 { 210 return null; 211 } 212 213 return load ( inputStream ); 214 } 215 216 public static Serializable load ( 217 String primaryFilename, 218 String fallbackFilename, 219 String fileContentsSpec, 220 Applet applet, 221 String persistenceKey, 222 ClassLoader classLoader, 223 String resourcePathFilename ) 224 throws ClassNotFoundException, IOException 225 ////////////////////////////////////////////////////////////////////// 226 { 227 Serializable serializable = null; 228 229 if ( primaryFilename != null ) 230 { 231 try 232 { 233 String userHomeDir = System.getProperty ( PROPERTY_USER_HOME ); 234 235 String primaryPath 236 = userHomeDir + File.separator + primaryFilename; 237 238 if ( fallbackFilename != null ) 239 { 240 String fallbackPath 241 = userHomeDir + File.separator + fallbackFilename; 242 243 serializable 244 = ( Serializable ) load ( primaryPath, fallbackPath ); 245 } 246 else 247 { 248 serializable = ( Serializable ) load ( primaryPath ); 249 } 250 } 251 catch ( FileNotFoundException ex ) 252 { 253 } 254 catch ( SecurityException ex ) 255 { 256 } 257 } 258 259 if ( ( serializable == null ) 260 && ( fileContentsSpec != null ) ) 261 { 262 try 263 { 264 serializable = ( Serializable ) 265 JnlpLib.loadSerializableUsingPersistenceService ( 266 fileContentsSpec ); 267 } 268 catch ( UnsupportedOperationException ex ) 269 { 270 } 271 } 272 273 if ( ( serializable == null ) 274 && ( applet != null ) 275 && ( persistenceKey != null ) ) 276 { 277 try 278 { 279 serializable = ( Serializable ) 280 AppletLib.loadSerializableUsingAppletPersistence ( 281 applet, persistenceKey ); 282 } 283 catch ( UnsupportedOperationException ex ) 284 { 285 } 286 } 287 288 if ( ( serializable == null ) 289 && ( classLoader != null ) 290 && ( resourcePathFilename != null ) ) 291 { 292 serializable 293 = ( Serializable ) load ( classLoader, resourcePathFilename ); 294 } 295 296 return serializable; 297 } 298 299 ////////////////////////////////////////////////////////////////////// 300 // save methods 301 ////////////////////////////////////////////////////////////////////// 302 303 public static void save ( 304 Serializable serializable, 305 OutputStream outputStream ) 306 throws IOException 307 ////////////////////////////////////////////////////////////////////// 308 { 309 NullArgumentException.check ( serializable ); 310 311 NullArgumentException.check ( outputStream ); 312 313 ObjectOutputStream objectOutputStream = null; 314 315 try 316 { 317 objectOutputStream = new ObjectOutputStream ( 318 new GZIPOutputStream ( 319 new BufferedOutputStream ( outputStream ) ) ); 320 321 objectOutputStream.writeObject ( serializable ); 322 } 323 finally 324 { 325 if ( objectOutputStream != null ) 326 { 327 objectOutputStream.close ( ); 328 } 329 else 330 { 331 outputStream.close ( ); 332 } 333 } 334 } 335 336 public static void save ( 337 Serializable serializable, 338 String filename, 339 boolean makeDirs ) 340 throws IOException 341 ////////////////////////////////////////////////////////////////////// 342 { 343 NullArgumentException.check ( serializable ); 344 345 NullArgumentException.check ( filename ); 346 347 if ( makeDirs ) 348 { 349 FileLib.makeParents ( filename ); 350 } 351 352 save ( serializable, new FileOutputStream ( filename ) ); 353 } 354 355 public static void save ( 356 Serializable serializable, 357 String filename ) 358 throws IOException 359 ////////////////////////////////////////////////////////////////////// 360 { 361 save ( serializable, filename, true ); 362 } 363 364 public static void save ( 365 Serializable serializable, 366 String latestFilename, 367 String backupFilename ) 368 throws IOException 369 ////////////////////////////////////////////////////////////////////// 370 { 371 NullArgumentException.check ( serializable ); 372 373 NullArgumentException.check ( latestFilename ); 374 375 NullArgumentException.check ( backupFilename ); 376 377 File latestFile = new File ( latestFilename ); 378 379 if ( latestFile.exists ( ) ) 380 { 381 File backupFile = new File ( backupFilename ); 382 383 if ( backupFile.exists ( ) ) 384 { 385 backupFile.delete ( ); 386 } 387 else 388 { 389 FileLib.makeParents ( backupFilename ); 390 } 391 392 latestFile.renameTo ( backupFile ); 393 } 394 395 save ( serializable, latestFilename ); 396 } 397 398 public static boolean save ( 399 Serializable serializable, 400 String latestFilename, 401 String backupFilename, 402 String fileContentsSpec, 403 Applet applet, 404 String persistenceKey ) 405 throws IOException 406 ////////////////////////////////////////////////////////////////////// 407 { 408 NullArgumentException.check ( serializable ); 409 410 if ( latestFilename != null ) 411 { 412 try 413 { 414 String userHomeDir = System.getProperty ( PROPERTY_USER_HOME ); 415 416 String latestPath 417 = userHomeDir + File.separator + latestFilename; 418 419 if ( backupFilename != null ) 420 { 421 String backupPath 422 = userHomeDir + File.separator + backupFilename; 423 424 save ( serializable, latestPath, backupPath ); 425 } 426 else 427 { 428 save ( serializable, latestPath ); 429 } 430 431 return true; 432 } 433 catch ( SecurityException ex ) 434 { 435 } 436 } 437 438 if ( fileContentsSpec != null ) 439 { 440 try 441 { 442 JnlpLib.saveSerializableUsingPersistenceService ( 443 fileContentsSpec, serializable ); 444 445 return true; 446 } 447 catch ( UnsupportedOperationException ex ) 448 { 449 } 450 } 451 452 if ( ( applet != null ) 453 && ( persistenceKey != null ) ) 454 { 455 try 456 { 457 AppletLib.saveSerializableUsingAppletPersistence ( 458 applet, persistenceKey, serializable ); 459 460 return true; 461 } 462 catch ( UnsupportedOperationException ex ) 463 { 464 } 465 } 466 467 return false; 468 } 469 470 ////////////////////////////////////////////////////////////////////// 471 ////////////////////////////////////////////////////////////////////// 472 473 private SerializableLib ( ) { } 474 475 ////////////////////////////////////////////////////////////////////// 476 ////////////////////////////////////////////////////////////////////// 477 }