1 22 package org.jboss.ejb3.cache.simple; 23 24 import java.io.BufferedInputStream ; 25 import java.io.File ; 26 import java.io.FileInputStream ; 27 import java.io.FileNotFoundException ; 28 import java.io.FileOutputStream ; 29 import java.io.IOException ; 30 import java.io.ObjectInputStream ; 31 import java.io.ObjectOutputStream ; 32 import java.security.AccessController ; 33 import java.security.PrivilegedAction ; 34 import java.security.PrivilegedActionException ; 35 import java.security.PrivilegedExceptionAction ; 36 import javax.ejb.EJBException ; 37 import org.jboss.ejb3.Container; 38 import org.jboss.ejb3.stateful.StatefulBeanContext; 39 import org.jboss.serial.io.JBossObjectInputStream; 40 import org.jboss.serial.io.JBossObjectOutputStream; 41 import org.jboss.system.server.ServerConfigLocator; 42 import org.jboss.util.id.UID; 43 44 67 public class StatefulSessionFilePersistenceManager implements StatefulSessionPersistenceManager 68 { 69 70 77 private String storeDirName = DEFAULT_STORE_DIRECTORY_NAME; 78 79 82 private File storeDir; 83 84 private Container con; 85 86 90 private boolean purgeEnabled = true; 91 92 106 public void setStoreDirectoryName(final String dirName) 107 { 108 this.storeDirName = dirName; 109 } 110 111 118 public String getStoreDirectoryName() 119 { 120 return storeDirName; 121 } 122 123 128 public void setPurgeEnabled(final boolean flag) 129 { 130 this.purgeEnabled = flag; 131 } 132 133 138 public boolean getPurgeEnabled() 139 { 140 return purgeEnabled; 141 } 142 143 148 public File getStoreDirectory() 149 { 150 return storeDir; 151 } 152 153 public void setContainer(Container con) 154 { 155 this.con = con; 156 } 157 158 163 public void initialize(Container con) throws Exception 164 { 165 this.con = con; 166 boolean debug = log.isDebugEnabled(); 167 168 170 String ejbName = con.getEjbName(); 171 172 File dir = ServerConfigLocator.locate().getServerTempDir(); 174 175 dir = new File (dir, storeDirName); 177 dir = new File (dir, ejbName + "-" + new UID().toString()); 179 storeDir = dir; 180 181 if (debug) 182 { 183 log.debug("Storing sessions for '" + ejbName + "' in: " + storeDir); 184 } 185 186 if (!storeDir.exists()) 188 { 189 if (MkdirsFileAction.mkdirs(storeDir) == false) 190 { 191 throw new IOException ("Failed to create directory: " + storeDir); 192 } 193 } 194 195 if (!storeDir.isDirectory()) 197 { 198 throw new IOException ("File exists where directory expected: " + storeDir); 199 } 200 201 if (!storeDir.canWrite() || !storeDir.canRead()) 203 { 204 throw new IOException ("Directory must be readable and writable: " + storeDir); 205 } 206 207 purgeAllSessionData(); 209 } 210 211 214 public void purgeAllSessionData() 215 { 216 if (!purgeEnabled) return; 217 218 log.debug("Purging all session data in: " + storeDir); 219 220 File [] sessions = storeDir.listFiles(); 221 for (int i = 0; i < sessions.length; i++) 222 { 223 if (!sessions[i].delete()) 224 { 225 log.warn("Failed to delete session state file: " + sessions[i]); 226 } 227 else 228 { 229 log.debug("Removed stale session state: " + sessions[i]); 230 } 231 } 232 } 233 234 237 public void destroy() throws Exception 238 { 239 purgeAllSessionData(); 241 242 if (purgeEnabled && !storeDir.delete()) 244 { 245 log.warn("Failed to delete session state storage directory: " + storeDir); 246 } 247 } 248 249 252 private File getFile(final Object id) 253 { 254 259 return new File (storeDir, String.valueOf(id) + ".ser"); 260 } 261 262 266 public StatefulBeanContext activateSession(Object id) 267 { 268 boolean debug = log.isDebugEnabled(); 269 if (debug) 270 { 271 log.debug("Attempting to activate; id=" + id); 272 } 273 274 File file = getFile(id); 276 if (debug) 277 { 278 log.debug("Reading session state from: " + file); 279 } 280 if (!file.exists()) return null; 281 282 StatefulBeanContext bean = null; 283 try 284 { 285 FileInputStream fis = FISAction.open(file); 286 ObjectInputStream in; 288 289 in = new JBossObjectInputStream(new BufferedInputStream (fis)); 290 try 291 { 292 bean = (StatefulBeanContext) in.readObject(); 293 } 294 finally 295 { 296 fis.close(); 297 in.close(); 298 } 299 } 300 catch (EJBException e) 301 { 302 throw e; 303 } 304 catch (Exception e) 305 { 306 throw new EJBException ("Could not activate; failed to " + 307 "restore state", e); 308 } 309 310 removePassivated(id); 311 312 bean.postActivate(); 313 return bean; 314 } 315 316 320 public void passivateSession(StatefulBeanContext ctx) 321 { 322 boolean debug = log.isDebugEnabled(); 323 if (debug) 324 { 325 log.debug("Attempting to passivate; id=" + ctx.getId()); 326 } 327 328 ctx.prePassivate(); 329 331 File file = getFile(ctx.getId()); 332 if (debug) 333 { 334 log.debug("Saving session state to: " + file); 335 } 336 337 try 338 { 339 FileOutputStream fos = FOSAction.open(file); 340 ObjectOutputStream out; 342 343 out = new JBossObjectOutputStream(fos, false); 344 345 try 346 { 347 out.writeObject(ctx); 348 out.flush(); 349 fos.flush(); 350 fos.close(); 351 } 352 finally 353 { 354 out.close(); 355 } 356 } 357 catch (EJBException e) 358 { 359 throw e; 360 } 361 catch (Exception e) 362 { 363 throw new EJBException ("Could not passivate; failed to save state", e); 364 } 365 366 if (debug) 367 { 368 log.debug("Passivation complete; id=" + ctx.getId()); 369 } 370 } 371 372 375 public void removePassivated(Object id) 376 { 377 boolean debug = log.isDebugEnabled(); 378 379 File file = getFile(id); 380 381 if (file.exists()) 383 { 384 if (debug) 385 { 386 log.debug("Removing passivated state file: " + file); 387 } 388 389 if (DeleteFileAction.delete(file) == false) 390 { 391 log.warn("Failed to delete passivated state file: " + file); 392 } 393 } 394 } 395 396 static class DeleteFileAction implements PrivilegedAction 397 { 398 File file; 399 400 DeleteFileAction(File file) 401 { 402 this.file = file; 403 } 404 405 public Object run() 406 { 407 boolean deleted = file.delete(); 408 return new Boolean (deleted); 409 } 410 411 static boolean delete(File file) 412 { 413 DeleteFileAction action = new DeleteFileAction(file); 414 Boolean deleted = (Boolean ) AccessController.doPrivileged(action); 415 return deleted.booleanValue(); 416 } 417 } 418 419 static class MkdirsFileAction implements PrivilegedAction 420 { 421 File file; 422 423 MkdirsFileAction(File file) 424 { 425 this.file = file; 426 } 427 428 public Object run() 429 { 430 boolean ok = file.mkdirs(); 431 return new Boolean (ok); 432 } 433 434 static boolean mkdirs(File file) 435 { 436 MkdirsFileAction action = new MkdirsFileAction(file); 437 Boolean ok = (Boolean ) AccessController.doPrivileged(action); 438 return ok.booleanValue(); 439 } 440 } 441 442 static class FISAction implements PrivilegedExceptionAction 443 { 444 File file; 445 446 FISAction(File file) 447 { 448 this.file = file; 449 } 450 451 public Object run() throws Exception 452 { 453 FileInputStream fis = new FileInputStream (file); 454 return fis; 455 } 456 457 static FileInputStream open(File file) throws FileNotFoundException 458 { 459 FISAction action = new FISAction(file); 460 FileInputStream fis = null; 461 try 462 { 463 fis = (FileInputStream ) AccessController.doPrivileged(action); 464 } 465 catch (PrivilegedActionException e) 466 { 467 throw (FileNotFoundException ) e.getException(); 468 } 469 470 return fis; 471 } 472 } 473 474 static class FOSAction implements PrivilegedExceptionAction 475 { 476 File file; 477 478 FOSAction(File file) 479 { 480 this.file = file; 481 } 482 483 public Object run() throws Exception 484 { 485 FileOutputStream fis = new FileOutputStream (file); 486 return fis; 487 } 488 489 static FileOutputStream open(File file) throws FileNotFoundException 490 { 491 FOSAction action = new FOSAction(file); 492 FileOutputStream fos = null; 493 try 494 { 495 fos = (FileOutputStream ) AccessController.doPrivileged(action); 496 } 497 catch (PrivilegedActionException e) 498 { 499 throw (FileNotFoundException ) e.getException(); 500 } 501 502 return fos; 503 } 504 } 505 } 506 | Popular Tags |