Source Code Cross Referenced for EJBUtil.java in  » Workflow-Engines » wfmopen-2.1.1 » de » danet » an » util » 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 » Workflow Engines » wfmopen 2.1.1 » de.danet.an.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * This file is part of the WfMOpen project.
003:         * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
004:         * All rights reserved.
005:         *
006:         * This program is free software; you can redistribute it and/or modify
007:         * it under the terms of the GNU General Public License as published by
008:         * the Free Software Foundation; either version 2 of the License, or
009:         * (at your option) any later version.
010:         *
011:         * This program is distributed in the hope that it will be useful,
012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014:         * GNU General Public License for more details.
015:         *
016:         * You should have received a copy of the GNU General Public License
017:         * along with this program; if not, write to the Free Software
018:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
019:         * 
020:         * $Id: EJBUtil.java,v 1.8 2007/03/27 21:59:42 mlipp Exp $
021:         *
022:         * $Log: EJBUtil.java,v $
023:         * Revision 1.8  2007/03/27 21:59:42  mlipp
024:         * Fixed lots of checkstyle warnings.
025:         *
026:         * Revision 1.7  2006/10/11 09:42:36  drmlipp
027:         * Comepleted adaption to local KeyGen EJB.
028:         *
029:         * Revision 1.6  2006/10/11 09:06:08  drmlipp
030:         * Fixed EJB naming.
031:         *
032:         * Revision 1.5  2006/10/11 07:47:02  drmlipp
033:         * Adapted properties file to new convention.
034:         *
035:         * Revision 1.4  2006/10/07 20:41:34  mlipp
036:         * Merged J2EE 1.4 adaptions from test branch.
037:         *
038:         * Revision 1.3  2006/09/29 12:32:08  drmlipp
039:         * Consistently using WfMOpen as projct name now.
040:         *
041:         * Revision 1.2  2005/09/10 21:44:18  mlipp
042:         * Fixed JDK 5.0 warnings.
043:         *
044:         * Revision 1.1.1.3  2004/08/18 15:17:34  drmlipp
045:         * Update to 1.2
046:         *
047:         * Revision 1.19  2004/02/13 10:32:22  lipp
048:         * Added support for local home interfaces.
049:         *
050:         * Revision 1.18  2003/10/27 15:28:51  lipp
051:         * Fixed repeat behaviour.
052:         *
053:         * Revision 1.17  2003/10/27 14:33:37  lipp
054:         * Added debug statements.
055:         *
056:         * Revision 1.16  2003/10/24 11:08:01  lipp
057:         * Added retrievJNDIEntry.
058:         *
059:         * Revision 1.15  2003/10/22 15:58:45  lipp
060:         * Fixed synchronization problem.
061:         *
062:         * Revision 1.14  2003/09/09 13:38:47  lipp
063:         * Added support for local home and business interfaces.
064:         *
065:         * Revision 1.13  2003/06/29 19:50:07  lipp
066:         * Moved primary key generator fropm JDBCUtil to EJBUtil and made some
067:         * fixes.
068:         *
069:         * Revision 1.12  2003/06/27 08:51:47  lipp
070:         * Fixed copyright/license information.
071:         *
072:         * Revision 1.11  2003/05/23 15:42:41  lipp
073:         * Fixed deployment unit dependencies.
074:         *
075:         * Revision 1.10  2003/03/31 16:50:27  huaiyang
076:         * Logging using common-logging.
077:         *
078:         * Revision 1.9  2002/09/26 15:05:13  lipp
079:         * Added method and extended comments.
080:         *
081:         * Revision 1.8  2002/08/30 13:37:04  lipp
082:         * Using Workflow engine facade now.
083:         *
084:         * Revision 1.7  2002/07/29 21:03:57  lipp
085:         * Some JavaDoc fixes.
086:         *
087:         * Revision 1.6  2002/07/24 05:48:16  huaiyang
088:         * javadocs added.
089:         *
090:         * Revision 1.5  2002/07/03 11:02:17  lipp
091:         * New session ejb handling support.
092:         *
093:         * Revision 1.4  2002/02/06 16:02:29  lipp
094:         * Added caching for home interfaces.
095:         *
096:         * Revision 1.3  2001/12/12 14:11:45  lipp
097:         * Added environment lookup.
098:         *
099:         * Revision 1.2  2001/10/25 17:02:13  robert
100:         * javadoc
101:         *
102:         * Revision 1.1  2001/10/25 07:41:23  lipp
103:         * Moved EJBUtil to de.danet.an.util
104:         *
105:         * Revision 1.1  2001/10/21 20:03:00  lipp
106:         * Initial version
107:         *
108:         */
109:
110:        package de.danet.an.util;
111:
112:        import java.io.IOException;
113:        import java.io.InputStream;
114:
115:        import java.util.HashMap;
116:        import java.util.Map;
117:        import java.util.Properties;
118:
119:        import java.lang.reflect.InvocationTargetException;
120:        import java.lang.reflect.Method;
121:        import java.rmi.RemoteException;
122:
123:        import javax.ejb.CreateException;
124:        import javax.ejb.EJBException;
125:        import javax.ejb.EJBHome;
126:        import javax.ejb.EJBLocalHome;
127:        import javax.ejb.EJBLocalObject;
128:        import javax.ejb.EJBObject;
129:        import javax.ejb.RemoveException;
130:        import javax.naming.CommunicationException;
131:        import javax.naming.InitialContext;
132:        import javax.naming.InterruptedNamingException;
133:        import javax.naming.NamingException;
134:        import javax.rmi.PortableRemoteObject;
135:
136:        /**
137:         * Collection of EJB utilities.
138:         * This class adds common utilitites for an EJB environment.
139:         */
140:        public class EJBUtil {
141:
142:            private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
143:                    .getLog(EJBUtil.class);
144:
145:            /**
146:             * The initial context used for lookup.
147:             */
148:            private static InitialContext initialContext = null;
149:
150:            /** Size of low key. */
151:            private static int lowKeySize = 64;
152:
153:            /** Key generation EJB name. */
154:            private static String keyGenEjbName = null;
155:
156:            /** Key generation high table. */
157:            private static String keyGenTable = null;
158:
159:            /**
160:             * Lookup a JNDI entry. This method implements caching as not all
161:             * application servers implement JNDI efficiently. As a
162:             * consequence, this method can only be used for read-only entries
163:             * that do not change over time.
164:             *
165:             * @param entry the JNDI name of the entry
166:             * @return the object found object
167:             * @throws NamingException if the JNDI lookup fails.
168:             */
169:            public static Object lookupJNDIEntry(String entry)
170:                    throws NamingException {
171:                if (initialContext == null) {
172:                    initialContext = new InitialContext();
173:                }
174:                Object objref = null;
175:                try {
176:                    objref = initialContext.lookup(entry);
177:                } catch (NamingException ne) {
178:                    // maybe naming context is no longer valid (e.g. cluster), retry
179:                    initialContext = new InitialContext();
180:                    objref = initialContext.lookup(entry);
181:                }
182:                return objref;
183:            }
184:
185:            /**
186:             * Lookup a JNDI entry using {@link #lookupJNDIEntry
187:             * <code>lookupJNDIEntry</code>}. This should be called from a
188:             * context where the JNDI name is expected
189:             * to exist. <code>NamingException</code>s should thus only occur
190:             * if the service is not available due to dynamic error conditions
191:             * (network failure etc.). These exceptions are mapped to a
192:             * <code>ResourceNotAvailable</code> exception.<P>
193:             *
194:             * If, nevertheless, the <code>NamingException</code> indicates
195:             * that the JNDI entry does not exists, we assume a configuration
196:             * error and throw an <code>IllegalStateException</code>.
197:             *
198:             * @param entry the JNDI name
199:             * @return an EJBHome object
200:             * @throws ResourceNotAvailableException if a problem occurs that
201:             * should be temporary.
202:             * @throws IllegalStateException if the given
203:             * <code>jndiName</code> is not registered.
204:             */
205:            public static Object retrieveJNDIEntry(String entry)
206:                    throws ResourceNotAvailableException, IllegalStateException {
207:                try {
208:                    return lookupJNDIEntry(entry);
209:                } catch (CommunicationException e) {
210:                    logger.error(e.getMessage(), e);
211:                    throw new ResourceNotAvailableException(e.getMessage());
212:                } catch (InterruptedNamingException e) {
213:                    logger.error(e.getMessage(), e);
214:                    throw new ResourceNotAvailableException(e.getMessage());
215:                } catch (NamingException e) {
216:                    logger.error(e.getMessage(), e);
217:                    throw new IllegalStateException(e.getMessage());
218:                }
219:            }
220:
221:            private static Map homeCache = new HashMap();
222:
223:            /**
224:             * Lookup a home interface using {@link #lookupJNDIEntry
225:             * <code>lookupJNDIEntry</code>}.
226:             *
227:             * The method provides caching of looked up home interface
228:             * if the JNDI name is global (i.e. does not start with
229:             * "<code>java:comp/</code>").
230:             *
231:             * @param ejbClass the class of the home interface
232:             * @param jndiName the JNDI name of the home interface
233:             * @return an EJBHome object
234:             * @throws NamingException if the JNDI lookup fails.
235:             */
236:            public static EJBHome lookupEJBHome(Class ejbClass, String jndiName)
237:                    throws NamingException {
238:                if (jndiName.startsWith("java:comp/")) {
239:                    Object objref = lookupJNDIEntry(jndiName);
240:                    return (EJBHome) PortableRemoteObject.narrow(objref,
241:                            ejbClass);
242:                }
243:                synchronized (homeCache) {
244:                    EJBHome ejbHome = (EJBHome) homeCache.get(jndiName);
245:                    if (ejbHome == null) {
246:                        ejbHome = (EJBHome) PortableRemoteObject.narrow(
247:                                lookupJNDIEntry(jndiName), ejbClass);
248:                        homeCache.put(jndiName, ejbHome);
249:                    }
250:                    return ejbHome;
251:                }
252:            }
253:
254:            /**
255:             * Return an EJB's home interface using {@link #lookupEJBHome
256:             * <code>lookupEJBHome</code>}. This should be called from a
257:             * context where the JNDI name of the home interface is expected
258:             * to exist. <code>NamingException</code>s should thus only occur
259:             * if the service is not available due to dynamic error conditions
260:             * (network failure etc.). These exceptions are mapped to a
261:             * <code>ResourceNotAvailable</code> exception.<P>
262:             *
263:             * If, nevertheless, the <code>NamingException</code> indicates
264:             * that the JNDI entry does not exists, we assume a configuration
265:             * error and throw an <code>IllegalStateException</code>.
266:             *
267:             * @param ejbClass the class of the home interface
268:             * @param jndiName the JNDI name of the home interface
269:             * @return an EJBHome object
270:             * @throws ResourceNotAvailableException if a problem occurs that
271:             * should be temporary.
272:             * @throws IllegalStateException if the given
273:             * <code>jndiName</code> is not registered.
274:             */
275:            public static EJBHome retrieveEJBHome(Class ejbClass,
276:                    String jndiName) throws ResourceNotAvailableException,
277:                    IllegalStateException {
278:                try {
279:                    return lookupEJBHome(ejbClass, jndiName);
280:                } catch (CommunicationException e) {
281:                    logger.error(e.getMessage(), e);
282:                    throw new ResourceNotAvailableException(e.getMessage());
283:                } catch (InterruptedNamingException e) {
284:                    logger.error(e.getMessage(), e);
285:                    throw new ResourceNotAvailableException(e.getMessage());
286:                } catch (NamingException e) {
287:                    logger.error(e.getMessage(), e);
288:                    throw new IllegalStateException(e.getMessage());
289:                }
290:            }
291:
292:            /**
293:             * Lookup a local home interface using {@link #lookupJNDIEntry
294:             * <code>lookupJNDIEntry</code>}.
295:             *
296:             * @param ejbClass the class of the home interface
297:             * @param jndiName the JNDI name of the home interface
298:             * @return an EJBHome object
299:             * @throws NamingException if the JNDI lookup fails.
300:             */
301:            public static EJBLocalHome lookupEJBLocalHome(Class ejbClass,
302:                    String jndiName) throws NamingException {
303:                Object objref = lookupJNDIEntry(jndiName);
304:                return (EJBLocalHome) PortableRemoteObject.narrow(objref,
305:                        ejbClass);
306:            }
307:
308:            /**
309:             * Return an EJB's local home interface using {@link
310:             * #lookupEJBHome <code>lookupEJBLocalHome</code>}. This should be
311:             * called from a context where the JNDI name of the home interface
312:             * is expected to exist. <code>NamingException</code>s should thus
313:             * only occur if the service is not available due to dynamic error
314:             * conditions (network failure etc.). These exceptions are mapped
315:             * to a <code>ResourceNotAvailable</code> exception.<P>
316:             *
317:             * If, nevertheless, the <code>NamingException</code> indicates
318:             * that the JNDI entry does not exists, we assume a configuration
319:             * error and throw an <code>IllegalStateException</code>.
320:             *
321:             * @param ejbClass the class of the home interface
322:             * @param jndiName the JNDI name of the home interface
323:             * @return an EJBHome object
324:             * @throws ResourceNotAvailableException if a problem occurs that
325:             * should be temporary.
326:             * @throws IllegalStateException if the given
327:             * <code>jndiName</code> is not registered.
328:             */
329:            public static EJBLocalHome retrieveEJBLocalHome(Class ejbClass,
330:                    String jndiName) throws ResourceNotAvailableException,
331:                    IllegalStateException {
332:                try {
333:                    return lookupEJBLocalHome(ejbClass, jndiName);
334:                } catch (CommunicationException e) {
335:                    logger.error(e.getMessage(), e);
336:                    throw new ResourceNotAvailableException(e.getMessage());
337:                } catch (InterruptedNamingException e) {
338:                    logger.error(e.getMessage(), e);
339:                    throw new ResourceNotAvailableException(e.getMessage());
340:                } catch (NamingException e) {
341:                    logger.error(e.getMessage(), e);
342:                    throw new IllegalStateException(e.getMessage());
343:                }
344:            }
345:
346:            /**
347:             * Create a session EJB. This method can be used for the special
348:             * &mdash; but very common &mdash; case when you want to create a
349:             * session EJB and the corresponding home interface has a create
350:             * method without any paramaters.<P>
351:             *
352:             * The given home interface is looked up using {@link
353:             * #retrieveEJBHome <code>retrieveEJBHome</code>} or {@link
354:             * #retrieveEJBLocalHome <code>retrieveEJBLocalHome</code>} (as
355:             * appropriate for the given class) and then the create session
356:             * method is called.
357:             *
358:             * @param ejbClass the class of the home interface which must define a
359:             * <code>create()</code> method.
360:             * @param jndiName the JNDI name of the home interface
361:             * @return the new <code>EJBObject</code>.
362:             * @throws IllegalArgumentException if no <code>create</code>
363:             * method without arguments exists.
364:             * @throws ResourceNotAvailableException if a problem occurs that
365:             * should be temporary.
366:             */
367:            public static Object createSession(Class ejbClass, String jndiName)
368:                    throws IllegalArgumentException,
369:                    ResourceNotAvailableException {
370:                if (EJBHome.class.isAssignableFrom(ejbClass)) {
371:                    EJBHome home = retrieveEJBHome(ejbClass, jndiName);
372:                    return createSession(home);
373:                } else {
374:                    EJBLocalHome home = retrieveEJBLocalHome(ejbClass, jndiName);
375:                    return createSession(home);
376:                }
377:            }
378:
379:            /**
380:             * Create a session EJB. This method can be used for the special -
381:             * but very common - case when you want to create a session EJB
382:             * and the corresponding home interface has a create method
383:             * without any paramaters.<P>
384:             *
385:             * @param home the home interface
386:             * @throws IllegalArgumentException if no <code>create</code>
387:             * method without arguments exists.
388:             * @throws ResourceNotAvailableException if a problem occurs that
389:             * should be temporary.
390:             * @return the new <code>EJBObject</code>.
391:             */
392:            public static EJBObject createSession(EJBHome home)
393:                    throws IllegalArgumentException,
394:                    ResourceNotAvailableException {
395:                Class homeClass = null;
396:                try {
397:                    homeClass = home.getClass();
398:                    Method createMethod = homeClass.getMethod("create",
399:                            (Class[]) null);
400:                    return (EJBObject) createMethod.invoke(home, new Object[0]);
401:                } catch (NoSuchMethodException nm) {
402:                    throw new IllegalArgumentException(homeClass.getName()
403:                            + " does not define a create() method.");
404:                } catch (IllegalAccessException ia) {
405:                    throw new IllegalArgumentException("Calling "
406:                            + homeClass.getName() + ".create() not allowed: "
407:                            + ia.getMessage());
408:                } catch (InvocationTargetException ie) {
409:                    Throwable tex = ie.getTargetException();
410:                    logger.warn("Exception in " + homeClass.getName()
411:                            + ".create():", unwrapEJBException(tex));
412:                    logger.warn("Unwrapped exception is:", tex);
413:                    if ((tex instanceof  RemoteException)
414:                            || (tex instanceof  CreateException)
415:                            || (tex instanceof  EJBException)) {
416:                        // these should be temporary conditions
417:                        throw new ResourceNotAvailableException(tex
418:                                .getMessage());
419:                    }
420:                    throw new IllegalArgumentException(tex.getMessage());
421:                }
422:            }
423:
424:            /**
425:             * Create a session EJB. This method can be used for the special -
426:             * but very common - case when you want to create a session EJB
427:             * and the corresponding home interface has a create method
428:             * without any paramaters.<P>
429:             *
430:             * @param home the home interface
431:             * @throws IllegalArgumentException if no <code>create</code>
432:             * method without arguments exists.
433:             * @throws ResourceNotAvailableException if a problem occurs that
434:             * should be temporary.
435:             * @return the new <code>EJBObject</code>.
436:             */
437:            public static EJBLocalObject createSession(EJBLocalHome home)
438:                    throws IllegalArgumentException,
439:                    ResourceNotAvailableException {
440:                Class homeClass = null;
441:                try {
442:                    homeClass = home.getClass();
443:                    Method createMethod = homeClass.getMethod("create",
444:                            (Class[]) null);
445:                    return (EJBLocalObject) createMethod.invoke(home,
446:                            new Object[0]);
447:                } catch (NoSuchMethodException nm) {
448:                    throw new IllegalArgumentException(homeClass.getName()
449:                            + " does not define a create() method.");
450:                } catch (IllegalAccessException ia) {
451:                    throw new IllegalArgumentException("Calling "
452:                            + homeClass.getName() + ".create() not allowed: "
453:                            + ia.getMessage());
454:                } catch (InvocationTargetException ie) {
455:                    Throwable tex = ie.getTargetException();
456:                    logger.warn("Exception in " + homeClass.getName()
457:                            + ".create():", unwrapEJBException(tex));
458:                    logger.warn("Unwrapped exception is:", tex);
459:                    if ((tex instanceof  RemoteException)
460:                            || (tex instanceof  CreateException)
461:                            || (tex instanceof  EJBException)) {
462:                        // these should be temporary conditions
463:                        throw new ResourceNotAvailableException(tex
464:                                .getMessage());
465:                    }
466:                    throw new IllegalArgumentException(tex.getMessage());
467:                }
468:            }
469:
470:            /**
471:             * Convenience method to clean up a session connection after
472:             * usage. If the given parameter is an instance of
473:             * <code>EJBObject</code> it simply calls <code>remove()</code> on
474:             * the given object. If the parameter is <code>null</code>
475:             * (indicating that the previous session creation propably failed)
476:             * nothing happens.  If an error occurs when calling
477:             * <code>remove()</code>, it will be logged as warning.
478:             * @param handle the &mdash; maybe &mdash; ejb session object.
479:             */
480:            public static void removeSession(Object handle) {
481:                if (handle == null || !(handle instanceof  EJBObject)) {
482:                    return;
483:                }
484:                try {
485:                    ((EJBObject) handle).remove();
486:                } catch (RemoveException rex) {
487:                    logger.warn("Error in remove(): " + rex.getMessage(), rex);
488:                } catch (RemoteException rex) {
489:                    logger.warn("Error in remove(): " + rex.getMessage(), rex);
490:                }
491:            }
492:
493:            /**
494:             * Unwrap the root cuase of an <code>EJBException</code>. The
495:             * <code>EJBException</code> wrappers often hide the root cause of
496:             * an exception. This method calls
497:             * <code>getCausedByException()</code> until it finds an exception
498:             * that is not of type <code>EJBException</code>. This exception
499:             * is returned.
500:             *
501:             * @param ex the exception to be unwrapped.
502:             * @return the root cause exception.
503:             */
504:            public static Throwable unwrapEJBException(Throwable ex) {
505:                while (ex instanceof  EJBException) {
506:                    ex = ((EJBException) ex).getCausedByException();
507:                }
508:                return ex;
509:            }
510:
511:            /**
512:             * Included database id values of each database tables. If a table is 
513:             * not present it is added.
514:             */
515:            private static Map counters = new HashMap();
516:
517:            private static class HighLow {
518:                public long high;
519:                public int low;
520:            }
521:
522:            /**
523:             * Gets the next unique primary key for the given database table
524:             * observing a minimum value.<P>
525:             *
526:             * This method uses a high/low algorithm. The high values are
527:             * obtained from an EJB that maintains a table in a database.
528:             * The JNDI name of the ejb used can be set in a properties file
529:             * "<code>/de.danet.an.util.jdbcKeyGen.properties</code> with the
530:             * entry "<code>generatorEjbJndiName</code>". <P>
531:             *
532:             * The JNDI name defaults to
533:             * "<code>java:comp/env/ejb/JdbcKeyGenLocal</code>". This reflects the
534:             * assumption that this method is usually called from an EJB or
535:             * servlet. Of course, the deployment descriptor of the calling
536:             * EJB or servlet must include an <code>&lt;ejb-ref&gt;</code>
537:             * entry that links to the local home of EJB "KeyGen".<P>
538:             *
539:             * The table used by the EJB can be set with the property
540:             * "<code>highKeyTable</code>". It defaults to
541:             * "<code>KeyGeneratorHighs</code>". This table must be created as:
542:             * <pre>create table KeyGeneratorHighs (
543:             *     TabName VARCHAR(50) NOT NULL,
544:             *     NextKey INTEGER NOT NULL
545:             * )/</pre><P>
546:             *
547:             * Another property that can be set is "<code>highFactor</code>".
548:             * It determines the number of low keys used before a new
549:             * high key is requested. This value defaults to 64.
550:             *
551:             * @param table the name of the table.
552:             * @param min the minimum value of the returned key.
553:             * @return the new primary key.
554:             * @throws ResourceNotAvailableException if an error occurs.
555:             */
556:            public static long newPrimaryKey(String table, long min)
557:                    throws ResourceNotAvailableException {
558:                try {
559:                    if (keyGenEjbName == null) {
560:                        Properties props = new Properties();
561:                        try {
562:                            InputStream is = JDBCUtil.class
563:                                    .getResourceAsStream("/de.danet.an.util.jdbcKeyGen.properties");
564:                            if (is != null) {
565:                                props.load(is);
566:                            }
567:                        } catch (IOException ex) {
568:                            logger.error("Cannot read jdbcKeyGen.properties: "
569:                                    + ex.getMessage(), ex);
570:                        }
571:                        keyGenTable = props.getProperty("highKeyTable",
572:                                "KeyGeneratorHighs");
573:                        lowKeySize = Integer.parseInt(props.getProperty(
574:                                "highFactor", "64"));
575:                        keyGenEjbName = props.getProperty(
576:                                "generatorEjbJndiName",
577:                                "java:comp/env/ejb/JdbcKeyGenLocal");
578:                    }
579:                    // now do the work
580:                    HighLow hl = null;
581:                    synchronized (counters) {
582:                        hl = (HighLow) counters.get(table);
583:                        if (hl == null) {
584:                            hl = new HighLow();
585:                            hl.low = lowKeySize - 1;
586:                            counters.put(table, hl);
587:                        }
588:                    }
589:                    synchronized (hl) {
590:                        if (logger.isDebugEnabled()) {
591:                            logger.debug("Finding new key for " + table
592:                                    + " using HighLow " + hl);
593:                        }
594:                        if (hl.low == (lowKeySize - 1)) {
595:                            KeyGenLocal keyGen = (KeyGenLocal) EJBUtil
596:                                    .createSession(KeyGenLocalHome.class,
597:                                            keyGenEjbName);
598:                            while (true) {
599:                                try {
600:                                    hl.high = keyGen.newHigh(keyGenTable,
601:                                            table, (min + lowKeySize - 1)
602:                                                    / lowKeySize);
603:                                    break;
604:                                } catch (EJBException e) {
605:                                    logger
606:                                            .info("Problem calling newHigh (will be "
607:                                                    + "repeated): "
608:                                                    + e.getMessage());
609:                                }
610:                            }
611:                            EJBUtil.removeSession(keyGen);
612:                            hl.low = 0;
613:                        }
614:                        return hl.high * lowKeySize + hl.low++;
615:                    }
616:                } catch (RemoteException e) {
617:                    logger.error("Cannot generate key: " + e.getMessage(), e);
618:                    throw new ResourceNotAvailableException(e.getMessage());
619:                }
620:            }
621:
622:            /**
623:             * Gets the next unique primary key for the given database table.
624:             * @param table the name of the table.
625:             * @return the new primary key.
626:             * @throws ResourceNotAvailableException if an error occurs.
627:             * @see #newPrimaryKey(String,long)
628:             */
629:            public static long newPrimaryKey(String table)
630:                    throws ResourceNotAvailableException {
631:                return newPrimaryKey(table, 0);
632:            }
633:
634:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.