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.gen;
031:
032: import com.caucho.config.*;
033: import com.caucho.ejb.cfg.*;
034: import com.caucho.java.JavaWriter;
035: import com.caucho.util.L10N;
036:
037: import javax.annotation.*;
038: import javax.ejb.*;
039: import java.io.IOException;
040: import java.lang.reflect.*;
041: import java.util.*;
042:
043: /**
044: * Represents any stateless view.
045: */
046: public class StatelessObjectView extends StatelessView {
047: private static final L10N L = new L10N(StatelessObjectView.class);
048:
049: public StatelessObjectView(StatelessGenerator bean, ApiClass api) {
050: super (bean, api);
051: }
052:
053: /**
054: * Introspects the APIs methods, producing a business method for
055: * each.
056: */
057: public void introspect() {
058: super .introspect();
059:
060: introspectLifecycle(getEjbClass().getJavaClass());
061: }
062:
063: /**
064: * Introspects the lifecycle methods
065: */
066: public void introspectLifecycle(Class cl) {
067: if (cl == null || cl.equals(Object.class))
068: return;
069:
070: for (Method method : cl.getDeclaredMethods()) {
071: if (method.isAnnotationPresent(PostConstruct.class)) {
072: }
073: }
074:
075: introspectLifecycle(cl.getSuperclass());
076: }
077:
078: /**
079: * Generates prologue for the context.
080: */
081: public void generateContextPrologue(JavaWriter out)
082: throws IOException {
083: String localVar = "_local_" + getApi().getSimpleName();
084:
085: out.println();
086: out.println("private " + getViewClassName() + " " + localVar
087: + ";");
088: }
089:
090: /**
091: * Generates context home's constructor
092: */
093: @Override
094: public void generateContextHomeConstructor(JavaWriter out)
095: throws IOException {
096: String localVar = "_local_" + getApi().getSimpleName();
097:
098: out.println(localVar + " = new " + getViewClassName()
099: + "(this);");
100: }
101:
102: /**
103: * Generates code to create the provider
104: */
105: @Override
106: public void generateCreateProvider(JavaWriter out, String var)
107: throws IOException {
108: String localVar = "_local_" + getApi().getSimpleName();
109:
110: out.println();
111: out.println("if (" + var + " == " + getApi().getName()
112: + ".class)");
113: out.println(" return " + localVar + ";");
114: }
115:
116: /**
117: * Generates code to create the provider
118: */
119: @Override
120: public void generateDestroy(JavaWriter out) throws IOException {
121: String localVar = "_local_" + getApi().getSimpleName();
122:
123: out.println();
124: out.println(localVar + ".destroy();");
125: }
126:
127: /**
128: * Generates the view code.
129: */
130: public void generate(JavaWriter out) throws IOException {
131: generateBean(out);
132:
133: generateProxy(out);
134: }
135:
136: /**
137: * Generates the view code.
138: */
139: public void generateBean(JavaWriter out) throws IOException {
140: out.println();
141: out.println("public static class " + getBeanClassName());
142: out.println(" extends " + getEjbClass().getName());
143: out.println("{");
144: out.pushDepth();
145:
146: out.println("private transient " + getViewClassName()
147: + " _context;");
148:
149: generateBusinessPrologue(out);
150:
151: out.println();
152: out.println(getBeanClassName() + "(" + getViewClassName()
153: + " context)");
154: out.println("{");
155: out.pushDepth();
156: out.println("_context = context;");
157:
158: generateBusinessConstructor(out);
159:
160: out.popDepth();
161: out.println("}");
162:
163: generateBusinessMethods(out);
164:
165: out.popDepth();
166: out.println("}");
167: }
168:
169: /**
170: * Generates the view code.
171: */
172: public void generateProxy(JavaWriter out) throws IOException {
173: out.println();
174: out.println("public static class " + getViewClassName());
175: generateExtends(out);
176: out.print(" implements " + getApi().getName());
177: out.println(", StatelessProvider");
178: out.println("{");
179: out.pushDepth();
180:
181: out.println("private " + getBean().getClassName()
182: + " _context;");
183: out.println("private " + getBeanClassName()
184: + " []_freeBeanStack" + " = new " + getBeanClassName()
185: + "[16];");
186: out.println("private int _freeBeanTop;");
187:
188: out.println();
189: out.println(getViewClassName() + "(" + getBean().getClassName()
190: + " context)");
191: out.println("{");
192: generateSuper(out, "context.getStatelessServer(), "
193: + getApi().getName() + ".class");
194: out.println(" _context = context;");
195:
196: out.println("}");
197:
198: out.println("public Object __caucho_get()");
199: out.println("{");
200: out.println(" return this;");
201: out.println("}");
202:
203: generateProxyPool(out);
204:
205: for (BusinessMethodGenerator bizMethod : getMethods()) {
206: out.println();
207:
208: bizMethod.generateHeader(out);
209: out.println("{");
210: out.pushDepth();
211:
212: out.println("Thread thread = Thread.currentThread();");
213: out
214: .println("ClassLoader oldLoader = thread.getContextClassLoader();");
215: out.println();
216: out.println("try {");
217: out.pushDepth();
218: out
219: .println("thread.setContextClassLoader(getStatelessServer().getClassLoader());");
220: out.println();
221:
222: generateProxyCall(out, bizMethod.getImplMethod());
223:
224: out.popDepth();
225: out.println("} finally {");
226: out.println(" thread.setContextClassLoader(oldLoader);");
227: out.println("}");
228:
229: out.popDepth();
230: out.println("}");
231: }
232:
233: out.popDepth();
234: out.println("}");
235: }
236:
237: protected void generateExtends(JavaWriter out) throws IOException {
238: out.println("extends StatelessObject");
239: }
240:
241: public void generateProxyPool(JavaWriter out) throws IOException {
242: String beanClass = getBeanClassName();
243:
244: out.println();
245: out.println(beanClass + " _ejb_begin()");
246: out.println("{");
247: out.pushDepth();
248: out.println(beanClass + " bean;");
249: out.println("synchronized (this) {");
250: out.println(" if (_freeBeanTop > 0) {");
251: out.println(" bean = _freeBeanStack[--_freeBeanTop];");
252: out.println(" return bean;");
253: out.println(" }");
254: out.println("}");
255: out.println();
256: out.println("try {");
257: out.println(" bean = new " + beanClass + "(this);");
258:
259: if (getBean().hasMethod("setSessionContext",
260: new Class[] { SessionContext.class })) {
261: out.println(" bean.setSessionContext(_context);");
262: }
263:
264: out.println(" getStatelessServer().initInstance(bean);");
265:
266: if (getBean().hasMethod("ejbCreate", new Class[0])) {
267: // ejb/0fe0: ejbCreate can be private, out.println(" bean.ejbCreate();");
268: out.println(" bean.ejbCreate();");
269:
270: // out.println(" invokeMethod(bean, \"ejbCreate\", new Class[] {}, new Object[] {});");
271: }
272:
273: out.println(" return bean;");
274: out.println("} catch (Exception e) {");
275: out
276: .println(" throw com.caucho.ejb.EJBExceptionWrapper.create(e);");
277: out.println("}");
278: out.popDepth();
279: out.println("}");
280:
281: out.println();
282: out.println("void _ejb_free(" + beanClass + " bean)");
283: out.println(" throws javax.ejb.EJBException");
284: out.println("{");
285: out.pushDepth();
286: out.println("if (bean == null)");
287: out.println(" return;");
288: out.println();
289: out.println("synchronized (this) {");
290: out.println(" if (_freeBeanTop < _freeBeanStack.length) {");
291: out.println(" _freeBeanStack[_freeBeanTop++] = bean;");
292: out.println(" return;");
293: out.println(" }");
294: out.println("}");
295:
296: /*
297: if (hasMethod("ejbRemove", new Class[0])) {
298: out.println();
299: // ejb/0fe0: ejbRemove() can be private, out.println("bean.ejbRemove();");
300: out.println("invokeMethod(bean, \"ejbRemove\", new Class[] {}, new Object[] {});");
301: }
302: */
303:
304: out.popDepth();
305: out.println("}");
306:
307: out.println();
308: out.println("public void destroy()");
309: out.println("{");
310: out.pushDepth();
311: out.println(beanClass + " ptr;");
312: out.println(beanClass + " []freeBeanStack;");
313: out.println("int freeBeanTop;");
314:
315: out.println("synchronized (this) {");
316: out.println(" freeBeanStack = _freeBeanStack;");
317: out.println(" freeBeanTop = _freeBeanTop;");
318: out.println(" _freeBeanStack = null;");
319: out.println(" _freeBeanTop = 0;");
320: out.println("}");
321:
322: if (getBean().hasMethod("ejbRemove", new Class[0])) {
323: out.println();
324: out.println("for (int i = 0; i < freeBeanTop; i++) {");
325: out.pushDepth();
326:
327: out.println("try {");
328: out.println(" if (freeBeanStack[i] != null)");
329: // ejb/0fe0: ejbRemove() can be private out.println(" freeBeanStack[i].ejbRemove();");
330: out.println(" freeBeanStack[i].ejbRemove();");
331: out.println("} catch (Throwable e) {");
332: out
333: .println(" __caucho_log.log(java.util.logging.Level.WARNING, e.toString(), e);");
334: out.println("}");
335:
336: out.popDepth();
337: out.println("}");
338: }
339:
340: out.popDepth();
341: out.println("}");
342: }
343:
344: public void generateProxyCall(JavaWriter out, Method implMethod)
345: throws IOException {
346: if (!void.class.equals(implMethod.getReturnType())) {
347: out.printClass(implMethod.getReturnType());
348: out.println(" result;");
349: }
350:
351: out.println(getBeanClassName() + " bean = _ejb_begin();");
352:
353: if (!void.class.equals(implMethod.getReturnType()))
354: out.print("result = ");
355:
356: out.print("bean." + implMethod.getName() + "(");
357:
358: Class[] types = implMethod.getParameterTypes();
359: for (int i = 0; i < types.length; i++) {
360: if (i != 0)
361: out.print(", ");
362:
363: out.print(" a" + i);
364: }
365:
366: out.println(");");
367:
368: out.println("_ejb_free(bean);");
369:
370: if (!void.class.equals(implMethod.getReturnType()))
371: out.println("return result;");
372: }
373:
374: protected void generateSuper(JavaWriter out, String serverVar)
375: throws IOException {
376: out.println("super(" + serverVar + ");");
377: }
378:
379: protected ApiMethod findImplMethod(ApiMethod apiMethod) {
380: return getEjbClass().getMethod(apiMethod);
381: }
382: }
|