Source Code Cross Referenced for CMPFilePersistenceManager.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.File;
025:        import java.io.InputStream;
026:        import java.io.OutputStream;
027:        import java.io.ObjectInputStream;
028:        import java.io.ObjectOutputStream;
029:        import java.io.FileOutputStream;
030:        import java.io.FileInputStream;
031:        import java.io.BufferedOutputStream;
032:        import java.io.BufferedInputStream;
033:        import java.io.IOException;
034:
035:        import java.lang.reflect.Method;
036:        import java.lang.reflect.Field;
037:
038:        import java.util.ArrayList;
039:        import java.util.Collection;
040:        import java.util.Collections;
041:        import java.util.Iterator;
042:
043:        import javax.ejb.EJBObject;
044:        import javax.ejb.Handle;
045:        import javax.ejb.CreateException;
046:        import javax.ejb.DuplicateKeyException;
047:        import javax.ejb.EJBException;
048:        import javax.ejb.FinderException;
049:        import javax.ejb.RemoveException;
050:
051:        import org.jboss.ejb.Container;
052:        import org.jboss.ejb.EntityContainer;
053:        import org.jboss.ejb.EntityPersistenceStore;
054:        import org.jboss.ejb.EntityEnterpriseContext;
055:        import org.jboss.ejb.GenericEntityObjectFactory;
056:        import org.jboss.metadata.EntityMetaData;
057:
058:        import org.jboss.system.server.ServerConfigLocator;
059:        import org.jboss.system.ServiceMBeanSupport;
060:
061:        import org.jboss.util.file.FilenameSuffixFilter;
062:
063:        /**
064:         * A file-based CMP entity bean persistence manager.
065:         *
066:         * <p>
067:         * Reads and writes entity bean objects to files by using the
068:         * standard Java serialization mechanism.
069:         * 
070:         * <p>
071:         * Enitiy state files are stored under:
072:         * <tt><em>jboss-server-data-dir</em>/<em>storeDirectoryName</em>/<em>ejb-name</em></tt>.
073:         *
074:         * <p>
075:         * Note, currently the name of the entity must be unique across the server, or
076:         * unless the store directory is changed, to avoid data collisions.
077:         * 
078:         * <p>
079:         * jason: disabled because XDoclet can not handle \u0000 right now
080:         * _@_jmx:mbean extends="org.jboss.system.ServiceMBean"
081:         * 
082:         * @version <tt>$Revision: 57209 $</tt>
083:         * @author <a href="mailto:rickard.oberg@telkel.com">Rickard Öberg</a>
084:         * @author <a href="mailto:marc.fleury@telkel.com">Marc Fleury</a>
085:         * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
086:         * <p><b>20010801 marc fleury:</b>
087:         * <ul>
088:         * <li>- insertion in cache upon create in now done in the instance interceptor
089:         * </ul>
090:         * <p><b>20011201 Dain Sundstrom:</b>
091:         * <ul>
092:         * <li>- added createBeanInstance and initEntity methods
093:         * </ul>
094:         * <p><b>20020525 Dain Sundstrom:</b>
095:         * <ul>
096:         * <li>- Replaced FinderResults with Collection
097:         * <li>- Removed unused method loadEntities
098:         * </ul>
099:         */
100:        public class CMPFilePersistenceManager extends ServiceMBeanSupport
101:                implements  EntityPersistenceStore /*, CMPFilePersistenceManagerMBean */
102:        {
103:            /** The default store directory name ("<tt>entities</tt>"). */
104:            public static final String DEFAULT_STORE_DIRECTORY_NAME = "entities";
105:
106:            /** Our container. */
107:            private EntityContainer con;
108:
109:            /**
110:             * The sub-directory name under the server data directory where
111:             * entity data is stored.
112:             *
113:             * @see #DEFAULT_STORE_DIRECTORY_NAME
114:             */
115:            private String storeDirName = DEFAULT_STORE_DIRECTORY_NAME;
116:
117:            /** The base directory where bean state will be stored. */
118:            private File storeDir;
119:
120:            /** A reference to the ID field for the entiy bean. */
121:            private Field idField;
122:
123:            /** Optional isModified method used by storeEntity. */
124:            private Method isModified;
125:
126:            /**
127:             * Saves a reference to the {@link EntityContainer} for
128:             * its bean type.
129:             *
130:             * @throws ClassCastException  Container is not a EntityContainer.
131:             */
132:            public void setContainer(final Container c) {
133:                con = (EntityContainer) c;
134:            }
135:
136:            //
137:            // jason: these properties are intended to be used when plugins/interceptors 
138:            //        can take configuration values (need to update xml schema and processors).
139:            //
140:
141:            /**
142:             * Set the sub-directory name under the server data directory
143:             * where entity data will be stored.
144:             *
145:             * <p>
146:             * This value will be appened to the value of
147:             * <tt><em>jboss-server-data-dir</em></tt>.
148:             *
149:             * <p>
150:             * This value is only used during creation and will not dynamically
151:             * change the store directory when set after the create step has finished.
152:             *
153:             * @jmx:managed-attribute
154:             *
155:             * @param dirName   A sub-directory name.
156:             */
157:            public void setStoreDirectoryName(final String dirName) {
158:                this .storeDirName = dirName;
159:            }
160:
161:            /**
162:             * Get the sub-directory name under the server data directory
163:             * where entity data is stored.
164:             *
165:             * @jmx:managed-attibute
166:             *
167:             * @see #setStoreDirectoryName
168:             *
169:             * @return A sub-directory name.
170:             */
171:            public String getStoreDirectoryName() {
172:                return storeDirName;
173:            }
174:
175:            /**
176:             * Returns the directory used to store entity state files.
177:             *
178:             * @jmx:managed-attibute
179:             * 
180:             * @return The directory used to store entity state files.
181:             */
182:            public File getStoreDirectory() {
183:                return storeDir;
184:            }
185:
186:            protected void createService() throws Exception {
187:                boolean debug = log.isDebugEnabled();
188:
189:                // Initialize the dataStore
190:
191:                String ejbName = con.getBeanMetaData().getEjbName();
192:
193:                // Get the system data directory
194:                File dir = ServerConfigLocator.locate().getServerDataDir();
195:
196:                //
197:                // jason: may have to use a generated token from container config
198:                //        to determine a unique name for this config for the given
199:                //        entity name.  it must persist through restarts though...
200:                //
201:
202:                // Setup the reference to the entity data store directory
203:                dir = new File(dir, storeDirName);
204:                dir = new File(dir, ejbName);
205:                storeDir = dir;
206:
207:                if (debug) {
208:                    log.debug("Storing entity state for '" + ejbName + "' in: "
209:                            + storeDir);
210:                }
211:
212:                // if the directory does not exist then try to create it
213:                if (!storeDir.exists()) {
214:                    if (!storeDir.mkdirs()) {
215:                        throw new IOException("Failed to create directory: "
216:                                + storeDir);
217:                    }
218:                }
219:
220:                // make sure we have a directory
221:                if (!storeDir.isDirectory()) {
222:                    throw new IOException(
223:                            "File exists where directory expected: " + storeDir);
224:                }
225:
226:                // make sure we can read and write to it
227:                if (!storeDir.canWrite() || !storeDir.canRead()) {
228:                    throw new IOException(
229:                            "Directory must be readable and writable: "
230:                                    + storeDir);
231:                }
232:
233:                // Get the ID field
234:                idField = con.getBeanClass().getField("id");
235:                if (debug)
236:                    log.debug("Using id field: " + idField);
237:
238:                // Lookup the isModified method if it exists
239:                try {
240:                    isModified = con.getBeanClass().getMethod("isModified",
241:                            new Class[0]);
242:                    if (!isModified.getReturnType().equals(Boolean.TYPE)) {
243:                        isModified = null; // Has to have "boolean" as return type!
244:                        log
245:                                .warn("Found isModified method, but return type is not boolean; ignoring");
246:                    } else {
247:                        if (debug)
248:                            log.debug("Using isModified method: " + isModified);
249:                    }
250:                } catch (NoSuchMethodException ignored) {
251:                }
252:            }
253:
254:            /**
255:             * Try to remove the store directory, if we can't then ignore.
256:             */
257:            protected void destroyService() throws Exception {
258:                storeDir.delete();
259:            }
260:
261:            public Object createBeanClassInstance() throws Exception {
262:                return con.getBeanClass().newInstance();
263:            }
264:
265:            /**
266:             * Reset all attributes to default value
267:             *
268:             * <p>
269:             * The EJB 1.1 specification is not entirely clear about this,
270:             * the EJB 2.0 spec is, see page 169.
271:             * Robustness is more important than raw speed for most server
272:             * applications, and not resetting atrribute values result in
273:             * *very* weird errors (old states re-appear in different instances and the
274:             * developer thinks he's on drugs).
275:             */
276:            public void initEntity(final EntityEnterpriseContext ctx) {
277:                // first get cmp metadata of this entity
278:                Object instance = ctx.getInstance();
279:                Class ejbClass = instance.getClass();
280:                Field cmpField;
281:                Class cmpFieldType;
282:
283:                EntityMetaData metaData = (EntityMetaData) con
284:                        .getBeanMetaData();
285:                Iterator i = metaData.getCMPFields();
286:
287:                while (i.hasNext()) {
288:                    // get the field declaration
289:                    try {
290:                        cmpField = ejbClass.getField((String) i.next());
291:                        cmpFieldType = cmpField.getType();
292:                        // find the type of the field and reset it
293:                        // to the default value
294:                        if (cmpFieldType.equals(boolean.class)) {
295:                            cmpField.setBoolean(instance, false);
296:                        } else if (cmpFieldType.equals(byte.class)) {
297:                            cmpField.setByte(instance, (byte) 0);
298:                        } else if (cmpFieldType.equals(int.class)) {
299:                            cmpField.setInt(instance, 0);
300:                        } else if (cmpFieldType.equals(long.class)) {
301:                            cmpField.setLong(instance, 0L);
302:                        } else if (cmpFieldType.equals(short.class)) {
303:                            cmpField.setShort(instance, (short) 0);
304:                        } else if (cmpFieldType.equals(char.class)) {
305:                            cmpField.setChar(instance, '\u0000');
306:                        } else if (cmpFieldType.equals(double.class)) {
307:                            cmpField.setDouble(instance, 0d);
308:                        } else if (cmpFieldType.equals(float.class)) {
309:                            cmpField.setFloat(instance, 0f);
310:                        } else {
311:                            cmpField.set(instance, null);
312:                        }
313:                    } catch (NoSuchFieldException e) {
314:                        // will be here with dependant value object's private attributes
315:                        // should not be a problem
316:                    } catch (Exception e) {
317:                        throw new EJBException(e);
318:                    }
319:                }
320:            }
321:
322:            public Object createEntity(final Method m, final Object[] args,
323:                    final EntityEnterpriseContext ctx) throws Exception {
324:                try {
325:                    Object id = idField.get(ctx.getInstance());
326:
327:                    // Check exist
328:                    if (getFile(id).exists())
329:                        throw new DuplicateKeyException("Already exists: " + id);
330:
331:                    // Store to file
332:                    storeEntity(id, ctx.getInstance());
333:
334:                    return id;
335:                } catch (IllegalAccessException e) {
336:                    throw new CreateException("Could not create entity: " + e);
337:                }
338:            }
339:
340:            public Object postCreateEntity(final Method m, final Object[] args,
341:                    final EntityEnterpriseContext ctx) throws Exception {
342:                return null;
343:            }
344:
345:            public Object findEntity(final Method finderMethod,
346:                    final Object[] args, final EntityEnterpriseContext ctx,
347:                    GenericEntityObjectFactory factory) throws FinderException {
348:                if (finderMethod.getName().equals("findByPrimaryKey")) {
349:                    if (!getFile(args[0]).exists())
350:                        throw new FinderException(args[0] + " does not exist");
351:
352:                    return factory.getEntityEJBObject(args[0]);
353:                }
354:
355:                return null;
356:            }
357:
358:            public Collection findEntities(final Method finderMethod,
359:                    final Object[] args, final EntityEnterpriseContext ctx,
360:                    GenericEntityObjectFactory factory) {
361:                if (finderMethod.getName().equals("findAll")) {
362:                    String[] files = storeDir.list(new FilenameSuffixFilter(
363:                            ".ser"));
364:                    ArrayList result = new ArrayList(files.length);
365:                    for (int i = 0; i < files.length; i++) {
366:                        final String key = files[i].substring(0, files[i]
367:                                .length() - 4);
368:                        result.add(factory.getEntityEJBObject(key));
369:                    }
370:
371:                    return result;
372:                } else {
373:                    // we only support find all
374:                    return Collections.EMPTY_LIST;
375:                }
376:            }
377:
378:            /**
379:             * Non-operation.
380:             */
381:            public void activateEntity(final EntityEnterpriseContext ctx) {
382:                // Nothing to do
383:            }
384:
385:            public void loadEntity(final EntityEnterpriseContext ctx) {
386:                try {
387:                    Object obj = ctx.getInstance();
388:
389:                    // Read fields
390:                    ObjectInputStream in = new CMPObjectInputStream(
391:                            new BufferedInputStream(new FileInputStream(
392:                                    getFile(ctx.getId()))));
393:
394:                    try {
395:                        Field[] f = obj.getClass().getFields();
396:                        for (int i = 0; i < f.length; i++) {
397:                            f[i].set(obj, in.readObject());
398:                        }
399:                    } finally {
400:                        in.close();
401:                    }
402:                } catch (Exception e) {
403:                    throw new EJBException("Load failed", e);
404:                }
405:            }
406:
407:            private void storeEntity(Object id, Object obj) {
408:                try {
409:                    // Store fields
410:                    ObjectOutputStream out = new CMPObjectOutputStream(
411:                            new BufferedOutputStream(new FileOutputStream(
412:                                    getFile(id))));
413:
414:                    try {
415:                        Field[] f = obj.getClass().getFields();
416:                        for (int i = 0; i < f.length; i++) {
417:                            out.writeObject(f[i].get(obj));
418:                        }
419:                    } finally {
420:                        out.close();
421:                    }
422:                } catch (Exception e) {
423:                    throw new EJBException("Store failed", e);
424:                }
425:            }
426:
427:            public boolean isStoreRequired(final EntityEnterpriseContext ctx)
428:                    throws Exception {
429:                if (isModified == null) {
430:                    return true;
431:                }
432:
433:                Boolean modified = (Boolean) isModified.invoke(ctx
434:                        .getInstance(), new Object[0]);
435:                return modified.booleanValue();
436:            }
437:
438:            public boolean isModified(EntityEnterpriseContext ctx)
439:                    throws Exception {
440:                return isStoreRequired(ctx);
441:            }
442:
443:            public void storeEntity(final EntityEnterpriseContext ctx) {
444:                storeEntity(ctx.getId(), ctx.getInstance());
445:            }
446:
447:            /**
448:             * Non-operation.
449:             */
450:            public void passivateEntity(final EntityEnterpriseContext ctx) {
451:                // This plugin doesn't do anything specific
452:            }
453:
454:            public void removeEntity(final EntityEnterpriseContext ctx)
455:                    throws RemoveException {
456:                // Remove file
457:                File file = getFile(ctx.getId());
458:
459:                if (!file.delete()) {
460:                    throw new RemoveException("Could not remove file: " + file);
461:                }
462:            }
463:
464:            protected File getFile(final Object id) {
465:                return new File(storeDir, String.valueOf(id) + ".ser");
466:            }
467:
468:            // Inner classes -------------------------------------------------
469:
470:            static class CMPObjectOutputStream extends ObjectOutputStream {
471:                public CMPObjectOutputStream(final OutputStream out)
472:                        throws IOException {
473:                    super (out);
474:                    enableReplaceObject(true);
475:                }
476:
477:                protected Object replaceObject(final Object obj)
478:                        throws IOException {
479:                    if (obj instanceof  EJBObject)
480:                        return ((EJBObject) obj).getHandle();
481:
482:                    return obj;
483:                }
484:            }
485:
486:            static class CMPObjectInputStream extends ObjectInputStream {
487:                public CMPObjectInputStream(final InputStream in)
488:                        throws IOException {
489:                    super (in);
490:                    enableResolveObject(true);
491:                }
492:
493:                protected Object resolveObject(final Object obj)
494:                        throws IOException {
495:                    if (obj instanceof  Handle)
496:                        return ((Handle) obj).getEJBObject();
497:
498:                    return obj;
499:                }
500:            }
501:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.