001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.ejb.gen21;
031:
032: import com.caucho.ejb.cfg21.EjbEntityBean;
033: import com.caucho.ejb.cfg.*;
034: import com.caucho.java.JavaWriter;
035: import com.caucho.java.gen.BaseClass;
036: import com.caucho.java.gen.BaseMethod;
037: import com.caucho.java.gen.ClassComponent;
038: import com.caucho.util.L10N;
039:
040: import javax.ejb.EntityContext;
041: import java.io.IOException;
042:
043: /**
044: * Generates the skeleton for a session bean.
045: */
046: public class EntityBean extends ClassComponent {
047: private final static L10N L = new L10N(EntityBean.class);
048:
049: private EjbEntityBean _bean;
050: private ApiClass _ejbClass;
051: protected String _implClassName;
052: protected String _contextClassName;
053:
054: protected BaseClass _beanClass;
055:
056: public EntityBean(ApiClass ejbClass, String contextClassName,
057: String implClassName) {
058: _ejbClass = ejbClass;
059: _contextClassName = contextClassName;
060: _implClassName = implClassName;
061:
062: _beanClass = new BeanImpl();
063: }
064:
065: /**
066: * Sets the bean.
067: */
068: public void setBean(EjbEntityBean bean) {
069: _bean = bean;
070: }
071:
072: /**
073: * Gets the bean.
074: */
075: public EjbEntityBean getBean() {
076: return _bean;
077: }
078:
079: /**
080: * Returns the implementation class name.
081: */
082: protected String getImplClassName() {
083: return _implClassName;
084: }
085:
086: /**
087: * Returns true for CMP.
088: */
089: protected boolean isCMP() {
090: return false;
091: }
092:
093: /**
094: * Generates the general entity information.
095: */
096: public void generate(JavaWriter out) throws IOException {
097: out
098: .println("protected static final java.util.logging.Logger __caucho_log = java.util.logging.Logger.getLogger(\""
099: + _contextClassName + "\");");
100:
101: generateContext(out);
102:
103: _beanClass.generate(out);
104: }
105:
106: protected void generateContext(JavaWriter out) throws IOException {
107: String shortContextName = _contextClassName;
108:
109: int p = shortContextName.lastIndexOf('.');
110: if (p > 0)
111: shortContextName = shortContextName.substring(p + 1);
112:
113: out.println();
114: out.println("Bean _ejb_free;");
115: out.println();
116: out.println("public " + shortContextName
117: + "(EntityServer server)");
118: out.println("{");
119: out.println(" super(server);");
120: out.println("}");
121:
122: out.println();
123: out
124: .println("Bean _ejb_begin(TransactionContext trans, boolean isHome, boolean doLoad)");
125: out.println("{");
126: out.pushDepth();
127:
128: // ejb/061c out.println("if (trans == null || isDead()) throw new IllegalStateException();");
129: out.println("if (isDead()) throw new IllegalStateException();");
130: out.println();
131: out.println("Bean ptr = null;");
132:
133: out.println("if (trans != null) {");
134: out.pushDepth();
135:
136: out.println("if (isHome)");
137: out.println(" ptr = (Bean) trans.getEntity(_server, null);");
138: out.println("else");
139:
140: if (isCMP())
141: out
142: .println(" ptr = (Bean) trans.getAmberEntity(_server, getPrimaryKey());");
143: else
144: out
145: .println(" ptr = (Bean) trans.getEntity(_server, getPrimaryKey());");
146:
147: out.popDepth();
148: out.println("}");
149:
150: out.println();
151: out.println("if (ptr != null)");
152: out.println(" return ptr;");
153:
154: // Otherwise create the bean
155: out.println();
156: out.println("synchronized (this) {");
157: out.println(" ptr = _ejb_free;");
158: out.println(" _ejb_free = null;");
159: out.println("}");
160:
161: /* XXX: Should be added if there is no transaction context yet,
162: e.g. findByPrimaryKey().
163:
164: out.println();
165: out.println("if (ptr == null && trans != null) {");
166: out.pushDepth();
167:
168: out.println("com.caucho.amber.manager.AmberConnection conn;");
169: out.println("conn = trans.getAmberConnection();");
170: out.println("ptr = (" + _bean.getSkeletonName() + ".Bean) conn.getSubEntity(" + _bean.getFullImplName() + ".class, getPrimaryKey());");
171:
172: out.popDepth();
173: out.println("}");
174: */
175:
176: out.println();
177: out.println("if (ptr == null) {");
178: out.pushDepth();
179: out.println("ptr = new Bean(this);");
180:
181: if (_ejbClass.hasMethod("ejbActivate", new Class[0])) {
182: // ejb/061c
183: out.println("if (trans != null && ! isHome)");
184: out
185: .println(" try { ptr.ejbActivate(); } catch (Exception e) { throw com.caucho.ejb.EJBExceptionWrapper.createRuntime(e); }");
186: }
187: out.popDepth();
188: out.println("}");
189:
190: if (isCMP()) {
191: out.println("if (! isHome) {");
192: out
193: .println(" ptr.__caucho_setPrimaryKey(getPrimaryKey());");
194: out
195: .println(" ptr.__caucho_setCacheItem(__caucho_getAmberCacheItem());");
196: out.println("}");
197: }
198:
199: out.println();
200: out.println("ptr._ejb_trans = trans;");
201:
202: out.println();
203: out.println("if (trans != null)");
204:
205: if (isCMP())
206: out.println(" trans.addAmberEntity(_server, ptr);");
207: else
208: out.println(" trans.addObject(ptr);");
209:
210: generateLoad(out);
211:
212: out.println("return ptr;");
213:
214: out.popDepth();
215: out.println("}");
216:
217: // XXX: need to optimize when no other transaction
218:
219: out.println();
220: out.println("public void _caucho_load()");
221: out.println(" throws FinderException");
222: out.println("{");
223: out.pushDepth();
224: out
225: .println("TransactionContext trans = _server.getTransactionManager().beginSingleRead();");
226:
227: out.println("try {");
228: out.pushDepth();
229:
230: if (isCMP()) {
231: out.println("if (trans == null)");
232: out.println(" __caucho_getAmberCacheItem();");
233: out.println("else");
234: out.println(" _ejb_begin(trans, false, true);");
235: } else {
236: out.println("if (trans == null) {");
237: out
238: .println(" Bean bean = _ejb_begin(trans, false, true);");
239: out.println(" bean._caucho_afterCompletion(true);");
240: out.println("}");
241: out.println("else");
242: out.println(" _ejb_begin(trans, false, true);");
243: }
244:
245: out.popDepth();
246: out.println("} catch (RuntimeException e) {");
247: out.println(" if (trans != null) trans.setRollbackOnly(e);");
248: out.println(" throw FinderExceptionWrapper.create(e);");
249: out.println("} finally {");
250: out.println(" if (trans != null)");
251: out.println(" trans.commit();");
252: out.println("}");
253: out.popDepth();
254: out.println("}");
255:
256: out.println();
257: out.println("public void update()");
258: out.println("{");
259: out.println("}");
260:
261: out.println();
262: out.println("public void _caucho_killCache()");
263: out.println(" throws javax.ejb.RemoveException");
264: out.println("{");
265: out.println("}");
266:
267: generateDestroy(out);
268: }
269:
270: /**
271: * Generates the cleanup code when the object is removed.
272: */
273: protected void generateDestroy(JavaWriter out) throws IOException {
274: out.println();
275: out.println("public void destroy()");
276: out.println(" throws Exception");
277: out.println("{");
278: out.pushDepth();
279: out.println("Bean bean;");
280: out.println("synchronized (this) {");
281: out.pushDepth();
282:
283: /*
284: if (_localClass != null) {
285: println("if (viewLocal != null)");
286: println(" viewLocal.destroy();");
287: println("viewLocal = null;");
288: }
289:
290: if (_remoteClass != null) {
291: println("if (viewRemote != null)");
292: println(" viewRemote.destroy();");
293: println("viewRemote = null;");
294: }
295: */
296: out.println("super.destroy();");
297: out.println();
298: out.println("bean = _ejb_free;");
299: out.println("_ejb_free = null;");
300: out.popDepth();
301: out.println("}");
302:
303: out.println();
304: out.println("if (bean != null) {");
305: out.pushDepth();
306:
307: if (hasMethod("ejbPassivate", new Class[0])) {
308: out
309: .println("if (bean._ejb_state > QEntity._CAUCHO_IS_HOME)");
310: out.println(" bean.ejbPassivate();");
311: }
312:
313: if (hasMethod("unsetEntityContext", new Class[0]))
314: out.println("bean.unsetEntityContext();");
315:
316: out.popDepth();
317: out.println("}");
318:
319: out.popDepth();
320: out.println("}");
321: }
322:
323: /**
324: * Adds a bean method.
325: */
326: void addMethod(BaseMethod method) {
327: if (method != null)
328: _beanClass.addMethod(method);
329: }
330:
331: /**
332: * Adds a bean component.
333: */
334: void addComponent(ClassComponent component) {
335: if (component != null)
336: _beanClass.addComponent(component);
337: }
338:
339: /**
340: * Returns true if the method is implemented.
341: */
342: protected boolean hasMethod(String methodName, Class[] paramTypes) {
343: return _ejbClass.hasMethod(methodName, paramTypes);
344: }
345:
346: /**
347: * Generates the load code.
348: */
349: protected void generateLoad(JavaWriter out) throws IOException {
350: if (hasMethod("ejbLoad", new Class[0])) {
351: out.println("if (doLoad) {");
352: out.println(" try {");
353: if (hasMethod("ejbLoad", new Class[0]))
354: out.println(" ptr.ejbLoad();");
355:
356: out
357: .println(" } catch (Exception e) { throw com.caucho.ejb.EJBExceptionWrapper.createRuntime(e); }");
358: // out.println(" ptr._ejb_state = QEntity._CAUCHO_IS_DIRTY;");
359: out
360: .println(" ptr._ejb_state = QEntity._CAUCHO_IS_LOADED;");
361: out.println("}");
362: }
363: }
364:
365: class BeanImpl extends BaseClass {
366: BeanImpl() {
367: super ("Bean", _implClassName);
368:
369: addInterfaceName("QEntity");
370:
371: setStatic(true);
372: }
373:
374: public void generateClassContent(JavaWriter out)
375: throws IOException {
376: out.println();
377: out
378: .println("protected final static java.util.logging.Logger __caucho_log = com.caucho.log.Log.open("
379: + _ejbClass.getName() + ".class);");
380: out.println("private static int __caucho_dbg_id;");
381: out.println("private final String __caucho_id;");
382:
383: out.println("Bean _ejb_next;");
384:
385: out.println(_contextClassName + " _ejb_context;");
386: out.println("TransactionContext _ejb_trans;");
387: out.println("byte _ejb_state;");
388: out.println("byte _ejb_flags;");
389:
390: out.println();
391: getBean().generateBeanPrologue(out);
392:
393: out.println();
394: out.println("Bean(" + _contextClassName + " context)");
395: out.println("{");
396: out.pushDepth();
397:
398: out.println("__caucho_id = \"\" + __caucho_dbg_id++ + \":"
399: + _ejbClass.getName() + "\";");
400:
401: out.println("try {");
402: out.println(" _ejb_context = context;");
403: out.println(" _ejb_state = QEntity._CAUCHO_IS_HOME;");
404:
405: if (_ejbClass.hasMethod("setEntityContext",
406: new Class[] { EntityContext.class })) {
407: out.println(" setEntityContext(context);");
408: }
409:
410: /*
411: if (isCMP()) {
412: out.println("__caucho_setPrimaryKey(context.getPrimaryKey());");
413: }
414: */
415:
416: out.println("} catch (Exception e) {");
417: out
418: .println(" __caucho_log.log(java.util.logging.Level.FINE, e.toString(), e);");
419: out
420: .println(" throw com.caucho.ejb.EJBExceptionWrapper.create(e);");
421: out.println("}");
422:
423: out.popDepth();
424: out.println("}");
425:
426: if (_ejbClass.hasMethod("ejbActivate", new Class[0])) {
427: out.println();
428: out.println("public void ejbActivate()");
429: out.println("{");
430: out
431: .println(" if (__caucho_log.isLoggable(java.util.logging.Level.FINE))");
432: out
433: .println(" __caucho_log.fine(__caucho_id + \":activate()\");");
434: out.println();
435: out.println(" _ejb_state = _CAUCHO_IS_ACTIVE;");
436: /*
437: if (getContainerManagedPersistence())
438: out.println(" _caucho_setPrimaryKey(_ejb_context.getPrimaryKey());");
439: */
440: out
441: .println(" try {super.ejbActivate(); } catch (Exception e) { throw com.caucho.ejb.EJBExceptionWrapper.createRuntime(e); }");
442: out.println("}");
443: }
444:
445: if (_ejbClass.hasMethod("ejbPassivate", new Class[0])) {
446: out.println();
447: out.println("public void ejbPassivate()");
448: out.println("{");
449: out
450: .println(" if (__caucho_log.isLoggable(java.util.logging.Level.FINE))");
451: out
452: .println(" __caucho_log.fine(__caucho_id + \":passivate()\");");
453: out.println(" super.ejbPassivate();");
454: out.println("}");
455: }
456:
457: out.println();
458: out
459: .println("public boolean _caucho_isMatch(com.caucho.ejb.AbstractServer server, Object primaryKey)");
460: out.println("{");
461: out.println(" if (server != _ejb_context.getServer())");
462: out.println(" return false;");
463: out
464: .println(" Object key = _ejb_context._caucho_getPrimaryKey();");
465: out
466: .println(" return (primaryKey == key || primaryKey != null && primaryKey.equals(key));");
467: out.println("}");
468:
469: generateSync(out);
470: generateBeforeCompletion(out);
471: generateAfterCompletion(out);
472:
473: super .generateClassContent(out);
474: }
475: }
476:
477: /**
478: * Generates the sync code.
479: */
480: protected void generateSync(JavaWriter out) throws IOException {
481: out.println();
482: out.println("public void _caucho_sync()");
483: out.println("{");
484:
485: if (_ejbClass.hasMethod("ejbStore", new Class[0])) {
486: out.pushDepth();
487: out.println("if (this._ejb_state >= _CAUCHO_IS_ACTIVE) {");
488: // if (! getContainerManagedPersistence())
489: out.println(" this._ejb_state = _CAUCHO_IS_LOADED;");
490: out.println(" ejbStore();");
491: out.println("}");
492: out.popDepth();
493: }
494:
495: out.println("}");
496: }
497:
498: /**
499: * Generates the before transaction completion code.
500: */
501: protected void generateBeforeCompletion(JavaWriter out)
502: throws IOException {
503: out.println();
504: out
505: .println("public void _caucho_beforeCompletion(boolean isCommit)");
506: out.println("{");
507:
508: if (_ejbClass.hasMethod("ejbStore", new Class[0])) {
509: out.pushDepth();
510:
511: generateStore(out);
512:
513: out.popDepth();
514: }
515: out.println("}");
516: }
517:
518: /**
519: * Generates the after transaction completion code.
520: */
521: protected void generateAfterCompletion(JavaWriter out)
522: throws IOException {
523:
524: // Frees the bean after it's done with the transaction.
525: out.println();
526: out
527: .println("public void _caucho_afterCompletion(boolean isCommit)");
528: out.println("{");
529: out.pushDepth();
530: out.println(_contextClassName + " cxt = (" + _contextClassName
531: + ") _ejb_context;");
532: out.println();
533: out.println("boolean isDead = false;");
534:
535: if (isCMP()) {
536: out.println("if (isCommit)");
537: out.println(" __caucho_afterCommit();");
538: out.println("else");
539: out.println(" __caucho_afterRollback();");
540: }
541:
542: out.println("if (! isCommit && _ejb_flags != 0) {");
543: out.println(" _ejb_state = QEntity._CAUCHO_IS_DEAD;");
544: out
545: .println(" cxt.getEntityServer().removeCache(cxt.getPrimaryKey());");
546: out.println("}");
547: out
548: .println("else if (_ejb_state == QEntity._CAUCHO_IS_REMOVED) {");
549: out
550: .println(" cxt.getEntityServer().removeCache(cxt.getPrimaryKey());");
551:
552: if (isCMP())
553: out.println(" _ejb_context.__amber_cacheItem = null;");
554:
555: out.println(" try {");
556: out.println(" cxt.destroy();");
557: out.println(" } catch (Exception e) {");
558: out.println(" }");
559:
560: out.println("}");
561: out.println("else {");
562: out.pushDepth();
563:
564: if (isCMP()) {
565: out.println("if (_ejb_context.__amber_cacheItem == null)");
566: out
567: .println(" _ejb_context.__amber_cacheItem = __caucho_cacheItem;");
568:
569: _bean.generateAfterCommit(out);
570: }
571: out.println("_ejb_trans = null;");
572: out.println("synchronized (this) {");
573: out.println(" if (_ejb_context._ejb_free == null) {");
574: // ejb/0252
575: // out.println(" __caucho_expire();"); // ejb/0aje
576: out.println(" _ejb_context._ejb_free = this;");
577: out.println(" return;");
578: out.println(" }");
579: out.println("}");
580:
581: if (hasMethod("ejbPassivate", new Class[0])) {
582: out.println("if (_ejb_state > QEntity._CAUCHO_IS_HOME)");
583: out.println(" ejbPassivate();");
584: }
585:
586: if (hasMethod("unsetEntityContext", new Class[0])) {
587: out.println();
588: out.println("unsetEntityContext();");
589: }
590:
591: out.popDepth();
592: out.println("}");
593: out.popDepth();
594: out.println("}");
595: }
596:
597: /**
598: * Generates the store code.
599: */
600: protected void generateStore(JavaWriter out) throws IOException {
601: out
602: .println("if (_ejb_state >= _CAUCHO_IS_LOADED && isCommit) {");
603: out.println(" _ejb_state = _CAUCHO_IS_LOADED;");
604: out.println(" ejbStore();");
605: out.println("}");
606: }
607: }
|