001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library 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 GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: EntityDesc.java 8097 2006-03-09 13:41:23Z durieuxp $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas_ejb.deployment.api;
025:
026: import java.util.Iterator;
027:
028: import org.objectweb.jonas_ejb.deployment.xml.AssemblyDescriptor;
029: import org.objectweb.jonas_ejb.deployment.xml.Entity;
030: import org.objectweb.jonas_ejb.deployment.xml.JonasEntity;
031: import org.objectweb.jonas_ejb.lib.BeanNaming;
032: import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
033: import org.objectweb.jonas_lib.deployment.xml.JLinkedList;
034: import org.objectweb.util.monolog.api.BasicLevel;
035:
036: /**
037: * Base class to hold meta-information related to an entity bean.
038: * @author Christophe Ney [cney@batisseurs.com] : Initial developer
039: * @author Helene Joanin
040: * @author Helene Joanin: take into account ejbSelect() methods.
041: * @author Helene Joanin: unsetting transaction attribute set to a default value.
042: */
043: public abstract class EntityDesc extends BeanDesc {
044:
045: /**
046: * remote methods for which no transaction attribute is to be set
047: */
048: protected static final String METHODS_REMOTE_NO_TX = ",getEJBHome,getHandle,getPrimaryKey,isIdentical,";
049:
050: /**
051: * home methods for which no transaction attribute is to be set
052: */
053: protected static final String METHODS_HOME_NO_TX = ",getEJBMetaData,getHomeHandle,";
054:
055: /**
056: * This field contains the class name of the factory instanciate by the
057: * container.
058: */
059: protected Class primaryKeyClass;
060: protected boolean reentrant;
061: protected int passivationTimeout = 0;
062: protected int inactivityTimeout = 0;
063: protected int deadlockTimeout = 20; // default = 20 sec.
064: protected int readTimeout = 15 * 60; // default = 15mn.
065: protected int maxWaitTime = 0; // default = 0s
066: protected boolean shared = false;
067: protected boolean prefetch = false;
068: protected boolean hardLimit = false;
069:
070: // Field used for pk auto-generate
071: protected boolean jdbcAutomaticPk = false; // first implementation with specific tag into JOnAS Descriptor file
072: protected boolean pkObjectType = false; // second implementation with prim-key-type=java.lang.Object (cf spec ?14.1.9.3)
073:
074: // mapping cleanup policy
075: public static final int CLEANUP_NONE = 0;
076: public static final int CLEANUP_CREATE = 1;
077: public static final int CLEANUP_REMOVEDATA = 2;
078: public static final int CLEANUP_REMOVEALL = 3;
079: protected int cleanup = CLEANUP_CREATE;
080:
081: // lock policy
082: public static final int LOCK_CONTAINER_READ_UNCOMMITTED = 0;
083: public static final int LOCK_CONTAINER_SERIALIZED = 1;
084: public static final int LOCK_CONTAINER_READ_COMMITTED = 2;
085: public static final int LOCK_DATABASE = 3;
086: public static final int LOCK_READ_ONLY = 4;
087: public static final int LOCK_CONTAINER_READ_WRITE = 5;
088: public static final int LOCK_CONTAINER_SERIALIZED_TRANSACTED = 6;
089: protected int lockPolicy = LOCK_CONTAINER_SERIALIZED;
090:
091: /**
092: * constructor to be used by parent node
093: */
094: public EntityDesc(ClassLoader classLoader, Entity ent,
095: AssemblyDescriptor asd, JonasEntity jEnt,
096: JLinkedList jMDRList, String fileName)
097: throws DeploymentDescException {
098:
099: super (classLoader, ent, jEnt, asd, jMDRList, fileName);
100:
101: // primary Key class
102: try {
103: // Test for automatic PK
104: if (ent.getPrimKeyClass().equalsIgnoreCase("Object")
105: || ent.getPrimKeyClass().equalsIgnoreCase(
106: "java.lang.Object")) {
107: primaryKeyClass = classLoader
108: .loadClass("java.lang.Integer");
109: pkObjectType = true;
110: } else
111: primaryKeyClass = classLoader.loadClass(ent
112: .getPrimKeyClass());
113: } catch (ClassNotFoundException e) {
114: throw new DeploymentDescException(
115: "Primary Key class not found for bean "
116: + this .ejbName, e);
117: }
118:
119: // passivation timeout
120: if (jEnt.getPassivationTimeout() != null) {
121: String tstr = jEnt.getPassivationTimeout();
122: Integer tval = new Integer(tstr);
123: passivationTimeout = tval.intValue();
124: }
125:
126: // inactivity timeout
127: if (jEnt.getInactivityTimeout() != null) {
128: String tstr = jEnt.getInactivityTimeout();
129: Integer tval = new Integer(tstr);
130: inactivityTimeout = tval.intValue();
131: }
132:
133: // deadlock timeout
134: if (jEnt.getDeadlockTimeout() != null) {
135: String tstr = jEnt.getDeadlockTimeout();
136: Integer tval = new Integer(tstr);
137: deadlockTimeout = tval.intValue();
138: }
139:
140: // read timeout
141: if (jEnt.getReadTimeout() != null) {
142: String tstr = jEnt.getReadTimeout();
143: Integer tval = new Integer(tstr);
144: readTimeout = tval.intValue();
145: }
146:
147: // max wait time
148: if (jEnt.getMaxWaitTime() != null) {
149: String tstr = jEnt.getMaxWaitTime();
150: Integer tval = new Integer(tstr);
151: maxWaitTime = tval.intValue();
152: }
153:
154: // reentrant
155: if (ent.getReentrant().equalsIgnoreCase("True")) {
156: reentrant = true;
157: } else if (ent.getReentrant().equalsIgnoreCase("False")) {
158: reentrant = false;
159: } else {
160: throw new DeploymentDescException(
161: "Invalid reentrant value for bean " + this .ejbName);
162: }
163:
164: // prefetch
165: if (jEnt.getPrefetch() != null) {
166: if (jEnt.getPrefetch().equalsIgnoreCase("True")) {
167: prefetch = true;
168: } else if (jEnt.getPrefetch().equalsIgnoreCase("False")) {
169: prefetch = false;
170: } else {
171: throw new DeploymentDescException(
172: "Invalid prefetch value for bean "
173: + this .ejbName);
174: }
175: }
176:
177: // hard limit
178: if (jEnt.getHardLimit() != null) {
179: if (jEnt.getHardLimit().equalsIgnoreCase("True")) {
180: hardLimit = true;
181: } else if (jEnt.getPrefetch().equalsIgnoreCase("False")) {
182: hardLimit = false;
183: } else {
184: throw new DeploymentDescException(
185: "Invalid hard-limit value for bean "
186: + this .ejbName);
187: }
188: }
189:
190: // min-pool-size
191: if (jEnt.getMinPoolSize() != null) {
192: String tstr = jEnt.getMinPoolSize();
193: Integer tval = new Integer(tstr);
194: poolMin = tval.intValue();
195: }
196:
197: // max-cache-size
198: if (jEnt.getMaxCacheSize() != null) {
199: String tstr = jEnt.getMaxCacheSize();
200: Integer tval = new Integer(tstr);
201: cacheMax = tval.intValue();
202: }
203:
204: // lock policy.
205: // Set default value for shared, depending on policy.
206: if (jEnt.getLockPolicy() != null) {
207: String tstr = jEnt.getLockPolicy();
208: if (tstr.equals("container-serialized")) {
209: lockPolicy = LOCK_CONTAINER_SERIALIZED;
210: shared = false;
211: } else if (tstr.equals("container-serialized-transacted")) {
212: lockPolicy = LOCK_CONTAINER_SERIALIZED_TRANSACTED;
213: shared = false;
214: } else if (tstr.equals("container-read-committed")) {
215: lockPolicy = LOCK_CONTAINER_READ_COMMITTED;
216: shared = true;
217: } else if (tstr.equals("container-read-uncommitted")) {
218: lockPolicy = LOCK_CONTAINER_READ_UNCOMMITTED;
219: shared = false;
220: } else if (tstr.equals("database")) {
221: lockPolicy = LOCK_DATABASE;
222: shared = true;
223: } else if (tstr.equals("read-only")) {
224: lockPolicy = LOCK_READ_ONLY;
225: shared = true;
226: } else if (tstr.equals("container-read-write")) {
227: lockPolicy = LOCK_CONTAINER_READ_WRITE;
228: shared = false;
229: } else {
230: throw new DeploymentDescException(
231: "Invalid lock-policy value for bean "
232: + jEnt.getEjbName());
233: }
234: }
235:
236: // shared
237: if (jEnt.getShared() != null) {
238: if (jEnt.getShared().equalsIgnoreCase("True")) {
239: shared = true;
240: } else if (jEnt.getShared().equalsIgnoreCase("False")) {
241: shared = false;
242: } else {
243: throw new DeploymentDescException(
244: "Invalid shared value for bean " + this .ejbName);
245: }
246: }
247:
248: // cleanup policy. Possible values are :
249: // create = create table only if does not exist yet. (default)
250: // none = nothing is done (not implemented)
251: // removeall = drop table and recreate it.
252: // removedata = remove all data if exist, create table if does not exist.
253: if (jEnt.getCleanup() != null) {
254: String tstr = jEnt.getCleanup();
255: if (tstr.equals("create")) {
256: cleanup = CLEANUP_CREATE;
257: } else if (tstr.equals("none")) {
258: cleanup = CLEANUP_NONE;
259: } else if (tstr.equals("removeall")) {
260: cleanup = CLEANUP_REMOVEALL;
261: } else if (tstr.equals("removedata")) {
262: cleanup = CLEANUP_REMOVEDATA;
263: } else {
264: throw new DeploymentDescException(
265: "Invalid cleanup value for bean "
266: + jEnt.getEjbName());
267: }
268: }
269:
270: // cache TxAttribute for ejbTimeout
271: for (Iterator i = getMethodDescIterator(); i.hasNext();) {
272: MethodDesc methd = (MethodDesc) i.next();
273: if (methd.getMethod().getName().equals("ejbTimeout")) {
274: timerTxAttribute = methd.getTxAttribute();
275: ejbTimeoutSignature = BeanNaming.getSignature(
276: getEjbName(), methd.getMethod());
277: }
278: }
279: }
280:
281: /**
282: * @return the cleanup policy for this bean
283: */
284: public int getCleanupPolicy() {
285: return cleanup;
286: }
287:
288: /**
289: * @return the lock policy for this bean
290: */
291: public int getLockPolicy() {
292: return lockPolicy;
293: }
294:
295: /**
296: * check that trans-attribute is valid for bean
297: */
298: protected void checkTxAttribute(MethodDesc md)
299: throws DeploymentDescException {
300: java.lang.reflect.Method m = md.getMethod();
301: if (md.getTxAttribute() == MethodDesc.TX_NOT_SET) {
302: // exclude method list for home interface
303: if (javax.ejb.EJBHome.class.isAssignableFrom(m
304: .getDeclaringClass())
305: && (METHODS_HOME_NO_TX.indexOf("," + m.getName()
306: + ",") != -1)) {
307: return;
308: }
309: // exclude method list for remote interface
310: if (javax.ejb.EJBObject.class.isAssignableFrom(m
311: .getDeclaringClass())
312: && (METHODS_REMOTE_NO_TX.indexOf("," + m.getName()
313: + ",") != -1)) {
314: return;
315: }
316: // exclude ejbSelect methods
317: if (md.isEjbSelect()) {
318: return;
319: }
320: // trans-attribute not set !
321: // trace a warning and set the tx-attribute with the default value
322: logger.log(BasicLevel.WARN,
323: "trans-attribute missing for method "
324: + m.toString() + " in entity bean "
325: + getEjbName()
326: + " (set to the default value "
327: + MethodDesc.TX_STR_DEFAULT_VALUE + ")");
328: md.setTxAttribute(MethodDesc.TX_STR_DEFAULT_VALUE);
329: }
330: }
331:
332: /**
333: * Get the passivation timeout value
334: */
335: public int getPassivationTimeout() {
336: return passivationTimeout;
337: }
338:
339: /**
340: * Get the inactivity timeout value
341: */
342: public int getInactivityTimeout() {
343: return inactivityTimeout;
344: }
345:
346: /**
347: * Get the deadlock timeout value
348: */
349: public int getDeadlockTimeout() {
350: return deadlockTimeout;
351: }
352:
353: /**
354: * Get the read timeout value
355: */
356: public int getReadTimeout() {
357: return readTimeout;
358: }
359:
360: /**
361: * Get the max wait time
362: */
363: public int getMaxWaitTime() {
364: return maxWaitTime;
365: }
366:
367: /**
368: * Get the entity's primary key class.
369: * @return Class for the primary key
370: */
371: public Class getPrimaryKeyClass() {
372: return primaryKeyClass;
373: }
374:
375: /**
376: * Assessor for reentrant entity bean
377: * @return true for reentrant entity bean
378: */
379: public boolean isReentrant() {
380: return reentrant;
381: }
382:
383: /**
384: * @return true for shared entity bean
385: */
386: public boolean isShared() {
387: return shared;
388: }
389:
390: /**
391: * @return true for prefetch entity bean
392: */
393: public boolean isPrefetch() {
394: return prefetch;
395: }
396:
397: /**
398: * @return true for hard-limit entity bean
399: */
400: public boolean isHardLimit() {
401: return hardLimit;
402: }
403:
404: /**
405: * Assessor for existence of automatic-pk element to True value
406: * @param field public field of the bean class
407: * @return true if automatic-pk element value is true else otherwise false
408: */
409: public boolean isAutomaticPk() {
410: return jdbcAutomaticPk;
411: }
412:
413: /**
414: * Assessor for primary key undefined (declare like java.lang.Object type)
415: * @param field public field of the bean class
416: * @return true if primary key is undefined (java.lang.Object type)
417: */
418: public boolean isUndefinedPK() {
419: return pkObjectType;
420: }
421:
422: /**
423: * String representation of the object for test purpose
424: * @return String representation of this object
425: */
426: public String toString() {
427: StringBuffer ret = new StringBuffer();
428: ret.append(super .toString());
429: ret.append("\nPrimaryKeyClass() ="
430: + getPrimaryKeyClass().toString());
431: ret.append("\nReentrant() =" + isReentrant());
432: ret
433: .append("\nPassivationTimeout() ="
434: + getPassivationTimeout());
435: ret.append("\nInactivityTimeout() =" + getInactivityTimeout());
436: ret.append("\nDeadlockTimeout() =" + getDeadlockTimeout());
437: ret.append("\nReadTimeout() =" + getReadTimeout());
438: ret.append("\nMaxWaitTime() =" + getMaxWaitTime());
439: ret.append("\nShared() =" + isShared());
440: ret.append("\nPoolMin() =" + getPoolMin());
441: ret.append("\nCacheMax() =" + getCacheMax());
442: return ret.toString();
443: }
444:
445: }
|