Source Code Cross Referenced for StatefulSessionFilePersistenceManager.java in  » EJB-Server-JBoss-4.2.1 » server » org » jboss » ejb » plugins » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server JBoss 4.2.1 » server » org.jboss.ejb.plugins 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.ejb.plugins;
023:
024:        import java.io.BufferedInputStream;
025:        import java.io.BufferedOutputStream;
026:        import java.io.File;
027:        import java.io.FileInputStream;
028:        import java.io.FileNotFoundException;
029:        import java.io.FileOutputStream;
030:        import java.io.IOException;
031:        import java.rmi.RemoteException;
032:        import java.security.AccessController;
033:        import java.security.PrivilegedAction;
034:        import java.security.PrivilegedActionException;
035:        import java.security.PrivilegedExceptionAction;
036:
037:        import javax.ejb.EJBException;
038:        import javax.ejb.RemoveException;
039:        import javax.ejb.SessionBean;
040:
041:        import org.jboss.ejb.AllowedOperationsAssociation;
042:        import org.jboss.ejb.Container;
043:        import org.jboss.ejb.StatefulSessionContainer;
044:        import org.jboss.ejb.StatefulSessionEnterpriseContext;
045:        import org.jboss.ejb.StatefulSessionPersistenceManager;
046:        import org.jboss.system.ServiceMBeanSupport;
047:        import org.jboss.system.server.ServerConfigLocator;
048:        import org.jboss.util.id.UID;
049:
050:        /**
051:         * A file-based stateful session bean persistence manager.
052:         * <p>
053:         * Reads and writes session bean objects to files by using the
054:         * standard Java serialization mechanism.
055:         * <p>
056:         * Passivated state files are stored under:
057:         * <tt><em>jboss-server-data-dir</em>/<em>storeDirectoryName</em>/<em>ejb-name</em>-<em>unique-id</em></tt>.
058:         * <p>
059:         * Since ejb-name is not unique across deployments we generate a <em>unique-id</em> to make
060:         * sure that beans with the same EJB name do not collide.
061:         *
062:         * @author <a href="mailto:rickard.oberg@telkel.com">Rickard �berg</a>
063:         * @author <a href="mailto:marc.fleury@telkel.com">Marc Fleury</a>
064:         * @author <a href="mailto:sebastien.alborini@m4x.org">Sebastien Alborini</a>
065:         * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
066:         * @author <a href="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
067:         * @version <tt>$Revision: 57209 $</tt>
068:         */
069:        public class StatefulSessionFilePersistenceManager extends
070:                ServiceMBeanSupport implements 
071:                StatefulSessionPersistenceManager,
072:                StatefulSessionFilePersistenceManagerMBean {
073:            /** The default store directory name ("<tt>sessions</tt>"). */
074:            public static final String DEFAULT_STORE_DIRECTORY_NAME = "sessions";
075:
076:            /** Our container. */
077:            private StatefulSessionContainer con;
078:
079:            /**
080:             * The sub-directory name under the server data directory where
081:             * session data is stored.
082:             *
083:             * @see #DEFAULT_STORE_DIRECTORY_NAME
084:             * @see #setStoreDirectoryName
085:             */
086:            private String storeDirName = DEFAULT_STORE_DIRECTORY_NAME;
087:
088:            /** The base directory where sessions state files are stored for our container. */
089:            private File storeDir;
090:
091:            /**
092:             * Enable purging leftover state files at create and destroy
093:             * time (default is true).
094:             */
095:            private boolean purgeEnabled = true;
096:
097:            /**
098:             * Saves a reference to the {@link StatefulSessionContainer} for
099:             * its bean type.
100:             *
101:             * @throws ClassCastException  Container is not a StatefulSessionContainer.
102:             */
103:            public void setContainer(final Container con) {
104:                this .con = (StatefulSessionContainer) con;
105:            }
106:
107:            //
108:            // jason: these properties are intended to be used when plugins/interceptors 
109:            //        can take configuration values (need to update xml schema and processors).
110:            //
111:
112:            /**
113:             * Set the sub-directory name under the server data directory
114:             * where session data will be stored.
115:             *
116:             * <p>
117:             * This value will be appened to the value of
118:             * <tt><em>jboss-server-data-dir</em></tt>.
119:             *
120:             * <p>
121:             * This value is only used during creation and will not dynamically
122:             * change the store directory when set after the create step has finished.
123:             *
124:             * @jmx:managed-attribute
125:             *
126:             * @param dirName   A sub-directory name.
127:             */
128:            public void setStoreDirectoryName(final String dirName) {
129:                this .storeDirName = dirName;
130:            }
131:
132:            /**
133:             * Get the sub-directory name under the server data directory
134:             * where session data is stored.
135:             *
136:             * jmx:managed-attribute
137:             *
138:             * @see #setStoreDirectoryName
139:             *
140:             * @return A sub-directory name.
141:             */
142:            public String getStoreDirectoryName() {
143:                return storeDirName;
144:            }
145:
146:            /**
147:             * Set the stale session state purge enabled flag.
148:             *
149:             * jmx:managed-attribute
150:             *
151:             * @param flag   The toggle flag to enable or disable purging.
152:             */
153:            public void setPurgeEnabled(final boolean flag) {
154:                this .purgeEnabled = flag;
155:            }
156:
157:            /**
158:             * Get the stale session state purge enabled flag.
159:             *
160:             * jmx:managed-attribute
161:             *
162:             * @return  True if purge is enabled.
163:             */
164:            public boolean getPurgeEnabled() {
165:                return purgeEnabled;
166:            }
167:
168:            /**
169:             * Returns the directory used to store session passivation state files.
170:             *
171:             * jmx:managed-attribute
172:             * 
173:             * @return The directory used to store session passivation state files.
174:             */
175:            public File getStoreDirectory() {
176:                return storeDir;
177:            }
178:
179:            /**
180:             * Setup the session data storage directory.
181:             *
182:             * <p>Purges any existing session data found.
183:             */
184:            protected void createService() throws Exception {
185:                // Initialize the dataStore
186:                String ejbName = con.getBeanMetaData().getEjbName();
187:
188:                // Get the system data directory
189:                File dir = ServerConfigLocator.locate().getServerTempDir();
190:
191:                // Setup the reference to the session data store directory
192:                dir = new File(dir, storeDirName);
193:                // ejbName is not unique across all deployments, so use a unique token
194:                dir = new File(dir, ejbName + "-" + new UID().toString());
195:                storeDir = dir;
196:
197:                log.debug("Storing sessions for '" + ejbName + "' in: "
198:                        + storeDir);
199:
200:                // if the directory does not exist then try to create it
201:                if (!storeDir.exists()) {
202:                    if (MkdirsFileAction.mkdirs(storeDir) == false) {
203:                        throw new IOException("Failed to create directory: "
204:                                + storeDir);
205:                    }
206:                }
207:
208:                // make sure we have a directory
209:                if (!storeDir.isDirectory()) {
210:                    throw new IOException(
211:                            "File exists where directory expected: " + storeDir);
212:                }
213:
214:                // make sure we can read and write to it
215:                if (!storeDir.canWrite() || !storeDir.canRead()) {
216:                    throw new IOException(
217:                            "Directory must be readable and writable: "
218:                                    + storeDir);
219:                }
220:
221:                // Purge state session state files, should be none, due to unique directory
222:                purgeAllSessionData();
223:            }
224:
225:            /**
226:             * Removes any state files left in the storgage directory.
227:             */
228:            private void purgeAllSessionData() {
229:                if (!purgeEnabled)
230:                    return;
231:
232:                log.debug("Purging all session data in: " + storeDir);
233:
234:                File[] sessions = storeDir.listFiles();
235:                for (int i = 0; i < sessions.length; i++) {
236:                    if (!sessions[i].delete()) {
237:                        log.warn("Failed to delete session state file: "
238:                                + sessions[i]);
239:                    } else {
240:                        log
241:                                .debug("Removed stale session state: "
242:                                        + sessions[i]);
243:                    }
244:                }
245:            }
246:
247:            /**
248:             * Purge any data in the store, and then the store directory too.
249:             */
250:            protected void destroyService() throws Exception {
251:                // Purge data and attempt to delete directory
252:                purgeAllSessionData();
253:
254:                // Nuke the directory too if purge is enabled
255:                if (purgeEnabled && !storeDir.delete()) {
256:                    log
257:                            .warn("Failed to delete session state storage directory: "
258:                                    + storeDir);
259:                }
260:            }
261:
262:            /**
263:             * Make a session state file for the given instance id.
264:             */
265:            private File getFile(final Object id) {
266:                //
267:                // jason: may have to translate id into a os-safe string, though
268:                //        the format of UID is safe on Unix and win32 already...
269:                //
270:
271:                return new File(storeDir, String.valueOf(id) + ".ser");
272:            }
273:
274:            /**
275:             * @return  A {@link UID}.
276:             */
277:            public Object createId(StatefulSessionEnterpriseContext ctx)
278:                    throws Exception {
279:                return new UID();
280:            }
281:
282:            /**
283:             * Non-operation.
284:             */
285:            public void createdSession(StatefulSessionEnterpriseContext ctx)
286:                    throws Exception {
287:                // nothing
288:            }
289:
290:            /**
291:             * Restores session state from the serialized file & invokes
292:             * {@link SessionBean#ejbActivate} on the target bean.
293:             */
294:            public void activateSession(
295:                    final StatefulSessionEnterpriseContext ctx)
296:                    throws RemoteException {
297:                boolean trace = log.isTraceEnabled();
298:                if (trace) {
299:                    log.trace("Attempting to activate; ctx=" + ctx);
300:                }
301:
302:                Object id = ctx.getId();
303:
304:                // Load state
305:                File file = getFile(id);
306:                if (trace) {
307:                    log.trace("Reading session state from: " + file);
308:                }
309:
310:                try {
311:                    FileInputStream fis = FISAction.open(file);
312:                    SessionObjectInputStream in = new SessionObjectInputStream(
313:                            ctx, new BufferedInputStream(fis));
314:
315:                    try {
316:                        Object obj = in.readObject();
317:                        if (trace) {
318:                            log.trace("Session state: " + obj);
319:                        }
320:                        ctx.setInstance(obj);
321:                    } finally {
322:                        in.close();
323:                    }
324:                } catch (Exception e) {
325:                    throw new EJBException("Could not activate; failed to "
326:                            + "restore state", e);
327:                }
328:
329:                removePassivated(id);
330:
331:                try {
332:                    // Instruct the bean to perform activation logic         
333:                    AllowedOperationsAssociation
334:                            .pushInMethodFlag(IN_EJB_ACTIVATE);
335:                    SessionBean bean = (SessionBean) ctx.getInstance();
336:                    bean.ejbActivate();
337:                } finally {
338:                    AllowedOperationsAssociation.popInMethodFlag();
339:                }
340:
341:                if (trace) {
342:                    log.trace("Activation complete; ctx=" + ctx);
343:                }
344:            }
345:
346:            /**
347:             * Invokes {@link SessionBean#ejbPassivate} on the target bean and saves the
348:             * state of the session to a file.
349:             */
350:            public void passivateSession(
351:                    final StatefulSessionEnterpriseContext ctx)
352:                    throws RemoteException {
353:                boolean trace = log.isTraceEnabled();
354:                if (trace) {
355:                    log.trace("Attempting to passivate; ctx=" + ctx);
356:                }
357:
358:                try {
359:                    // Instruct the bean to perform passivation logic    
360:                    AllowedOperationsAssociation
361:                            .pushInMethodFlag(IN_EJB_PASSIVATE);
362:                    SessionBean bean = (SessionBean) ctx.getInstance();
363:                    bean.ejbPassivate();
364:                } finally {
365:                    AllowedOperationsAssociation.popInMethodFlag();
366:                }
367:
368:                // Store state
369:
370:                File file = getFile(ctx.getId());
371:                if (trace) {
372:                    log.trace("Saving session state to: " + file);
373:                }
374:
375:                try {
376:                    FileOutputStream fos = FOSAction.open(file);
377:                    SessionObjectOutputStream out = new SessionObjectOutputStream(
378:                            new BufferedOutputStream(fos));
379:
380:                    Object obj = ctx.getInstance();
381:                    if (trace) {
382:                        log.trace("Writing session state: " + obj);
383:                    }
384:
385:                    try {
386:                        out.writeObject(obj);
387:                    } finally {
388:                        out.close();
389:                    }
390:                } catch (Exception e) {
391:                    throw new EJBException(
392:                            "Could not passivate; failed to save state", e);
393:                }
394:
395:                if (trace) {
396:                    log.trace("Passivation complete; ctx=" + ctx);
397:                }
398:            }
399:
400:            /**
401:             * Invokes {@link SessionBean#ejbRemove} on the target bean.
402:             */
403:            public void removeSession(final StatefulSessionEnterpriseContext ctx)
404:                    throws RemoteException, RemoveException {
405:                boolean trace = log.isTraceEnabled();
406:                if (trace) {
407:                    log.trace("Attempting to remove; ctx=" + ctx);
408:                }
409:
410:                // Instruct the bean to perform removal logic
411:                SessionBean bean = (SessionBean) ctx.getInstance();
412:                bean.ejbRemove();
413:
414:                if (trace) {
415:                    log.trace("Removal complete; ctx=" + ctx);
416:                }
417:            }
418:
419:            /**
420:             * Removes the saved state file (if any) for the given session id.
421:             */
422:            public void removePassivated(final Object id) {
423:                boolean trace = log.isTraceEnabled();
424:
425:                File file = getFile(id);
426:
427:                // only attempt to delete if the file exists
428:                if (file.exists()) {
429:                    if (trace) {
430:                        log.trace("Removing passivated state file: " + file);
431:                    }
432:
433:                    if (DeleteFileAction.delete(file) == false) {
434:                        log.warn("Failed to delete passivated state file: "
435:                                + file);
436:                    }
437:                }
438:            }
439:
440:            static class DeleteFileAction implements  PrivilegedAction {
441:                File file;
442:
443:                DeleteFileAction(File file) {
444:                    this .file = file;
445:                }
446:
447:                public Object run() {
448:                    boolean deleted = file.delete();
449:                    return new Boolean(deleted);
450:                }
451:
452:                static boolean delete(File file) {
453:                    DeleteFileAction action = new DeleteFileAction(file);
454:                    Boolean deleted = (Boolean) AccessController
455:                            .doPrivileged(action);
456:                    return deleted.booleanValue();
457:                }
458:            }
459:
460:            static class MkdirsFileAction implements  PrivilegedAction {
461:                File file;
462:
463:                MkdirsFileAction(File file) {
464:                    this .file = file;
465:                }
466:
467:                public Object run() {
468:                    boolean ok = file.mkdirs();
469:                    return new Boolean(ok);
470:                }
471:
472:                static boolean mkdirs(File file) {
473:                    MkdirsFileAction action = new MkdirsFileAction(file);
474:                    Boolean ok = (Boolean) AccessController
475:                            .doPrivileged(action);
476:                    return ok.booleanValue();
477:                }
478:            }
479:
480:            static class FISAction implements  PrivilegedExceptionAction {
481:                File file;
482:
483:                FISAction(File file) {
484:                    this .file = file;
485:                }
486:
487:                public Object run() throws Exception {
488:                    FileInputStream fis = new FileInputStream(file);
489:                    return fis;
490:                }
491:
492:                static FileInputStream open(File file)
493:                        throws FileNotFoundException {
494:                    FISAction action = new FISAction(file);
495:                    FileInputStream fis = null;
496:                    try {
497:                        fis = (FileInputStream) AccessController
498:                                .doPrivileged(action);
499:                    } catch (PrivilegedActionException e) {
500:                        throw (FileNotFoundException) e.getException();
501:                    }
502:
503:                    return fis;
504:                }
505:            }
506:
507:            static class FOSAction implements  PrivilegedExceptionAction {
508:                File file;
509:
510:                FOSAction(File file) {
511:                    this .file = file;
512:                }
513:
514:                public Object run() throws Exception {
515:                    FileOutputStream fis = new FileOutputStream(file);
516:                    return fis;
517:                }
518:
519:                static FileOutputStream open(File file)
520:                        throws FileNotFoundException {
521:                    FOSAction action = new FOSAction(file);
522:                    FileOutputStream fos = null;
523:                    try {
524:                        fos = (FileOutputStream) AccessController
525:                                .doPrivileged(action);
526:                    } catch (PrivilegedActionException e) {
527:                        throw (FileNotFoundException) e.getException();
528:                    }
529:
530:                    return fos;
531:                }
532:            }
533:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.