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.ejb3.gen;
031:
032: import com.caucho.ejb.cfg.*;
033: import com.caucho.ejb.gen.*;
034: import com.caucho.java.JavaWriter;
035: import com.caucho.java.gen.GenClass;
036: import com.caucho.java.gen.JavaClassGenerator;
037: import com.caucho.util.L10N;
038: import com.caucho.webbeans.component.*;
039:
040: import java.io.*;
041: import java.lang.reflect.*;
042: import java.lang.annotation.*;
043: import java.util.*;
044: import javax.ejb.*;
045: import javax.webbeans.*;
046:
047: /**
048: * Generates the skeleton for a session bean.
049: */
050: public class PojoBean extends BeanGenerator {
051: private static final L10N L = new L10N(PojoBean.class);
052:
053: private ApiClass _beanClass;
054:
055: private PojoView _view;
056:
057: private ArrayList<BusinessMethodGenerator> _businessMethods = new ArrayList<BusinessMethodGenerator>();
058:
059: private boolean _isEnhanced;
060: private boolean _hasXA;
061: private boolean _hasReadResolve;
062: private boolean _isReadResolveEnhanced;
063: private boolean _isSingleton;
064:
065: public PojoBean(Class beanClass) {
066: super (beanClass.getName() + "$ResinWebBean", new ApiClass(
067: beanClass));
068:
069: setSuperClassName(beanClass.getName());
070: addInterfaceName("java.io.Serializable");
071:
072: addImport("javax.transaction.*");
073:
074: _view = new PojoView(this , getEjbClass());
075:
076: _beanClass = new ApiClass(beanClass);
077: }
078:
079: public void setSingleton(boolean isSingleton) {
080: _isSingleton = isSingleton;
081: }
082:
083: public void introspect() {
084: for (ApiMethod method : _beanClass.getMethods()) {
085: if (Object.class.equals(method.getDeclaringClass()))
086: continue;
087:
088: if (method.getName().equals("readResolve")
089: && method.getParameterTypes().length == 0) {
090: _hasReadResolve = true;
091: }
092:
093: if (!method.isPublic() && !method.isProtected())
094: continue;
095: if (method.isStatic())
096: continue;
097: if (method.isFinal())
098: continue;
099:
100: int index = _businessMethods.size();
101: BusinessMethodGenerator bizMethod = new BusinessMethodGenerator(
102: _view, method, method.getMethod(), index);
103:
104: bizMethod
105: .introspect(method.getMethod(), method.getMethod());
106:
107: if (bizMethod.isEnhanced()) {
108: _isEnhanced = true;
109: _businessMethods.add(bizMethod);
110: }
111: }
112:
113: if (Serializable.class.isAssignableFrom(_beanClass
114: .getJavaClass())
115: && !_hasReadResolve
116: && hasTransientInject(_beanClass.getJavaClass())) {
117: _isReadResolveEnhanced = true;
118: _isEnhanced = true;
119: }
120: }
121:
122: private boolean hasTransientInject(Class cl) {
123: if (cl == null || Object.class.equals(cl))
124: return false;
125:
126: for (Field field : cl.getDeclaredFields()) {
127: if (!Modifier.isTransient(field.getModifiers()))
128: continue;
129: if (Modifier.isStatic(field.getModifiers()))
130: continue;
131:
132: Annotation[] annList = field.getDeclaredAnnotations();
133: if (annList == null)
134: continue;
135:
136: for (Annotation ann : annList) {
137: if (ann.annotationType().isAnnotationPresent(
138: BindingType.class))
139: return true;
140:
141: if (In.class.equals(ann.annotationType()))
142: return true;
143: }
144: }
145:
146: return hasTransientInject(cl.getSuperclass());
147: }
148:
149: public Class generateClass() {
150: if (!isEnhanced())
151: return _beanClass.getJavaClass();
152:
153: try {
154: JavaClassGenerator gen = new JavaClassGenerator();
155:
156: Class cl = gen.preload(getFullClassName());
157:
158: if (cl != null)
159: return cl;
160:
161: gen.generate(this );
162:
163: gen.compilePendingJava();
164:
165: return gen.loadClass(getFullClassName());
166: } catch (Exception e) {
167: throw new RuntimeException(e);
168: }
169: }
170:
171: protected boolean isEnhanced() {
172: return _isEnhanced;
173: }
174:
175: @Override
176: protected void generateClassContent(JavaWriter out)
177: throws IOException {
178: generateHeader(out);
179:
180: HashMap map = new HashMap();
181: for (BusinessMethodGenerator method : _businessMethods) {
182: method.generatePrologueTop(out, map);
183: }
184:
185: for (Constructor ctor : _beanClass.getJavaClass()
186: .getDeclaredConstructors()) {
187: if (Modifier.isPublic(ctor.getModifiers()))
188: generateConstructor(out, ctor);
189: }
190:
191: map = new HashMap();
192: for (BusinessMethodGenerator method : _businessMethods) {
193: method.generate(out, map);
194: }
195:
196: generateWriteReplace(out);
197: }
198:
199: /**
200: * Generates header and prologue data.
201: */
202: protected void generateHeader(JavaWriter out) throws IOException {
203: out
204: .println("private static final java.util.logging.Logger __log");
205: out.println(" = java.util.logging.Logger.getLogger(\""
206: + getFullClassName() + "\");");
207: out.println("private static final boolean __isFiner");
208: out
209: .println(" = __log.isLoggable(java.util.logging.Level.FINER);");
210:
211: if (_hasXA) {
212: out.println();
213: out
214: .println("private static final com.caucho.ejb3.xa.XAManager _xa");
215: out.println(" = new com.caucho.ejb3.xa.XAManager();");
216: }
217:
218: /*
219: if (_isReadResolveEnhanced)
220: generateReadResolve(out);
221: */
222: }
223:
224: protected void generateReadResolve(JavaWriter out)
225: throws IOException {
226: out.println();
227: out.println("private Object readResolve()");
228: out.println("{");
229: out.println(" System.out.println(\"resolve-me\");");
230:
231: out.println(" return this;");
232: out.println("}");
233: }
234:
235: protected void generateWriteReplace(JavaWriter out)
236: throws IOException {
237: if (_isSingleton) {
238: out.println("private transient Object __caucho_handle;");
239: out.println();
240: out.println("private Object writeReplace()");
241: out.println("{");
242: out.println(" return __caucho_handle;");
243: out.println("}");
244: } else {
245: // XXX: need a handle or serialize to the base class (?)
246: }
247: }
248:
249: protected void generateConstructor(JavaWriter out, Constructor ctor)
250: throws IOException {
251: Class[] paramTypes = ctor.getParameterTypes();
252:
253: out.print("public " + getClassName() + "(");
254:
255: for (int i = 0; i < paramTypes.length; i++) {
256: if (i != 0)
257: out.print(", ");
258:
259: out.printClass(paramTypes[i]);
260: out.print(" a" + i);
261: }
262:
263: out.println(")");
264:
265: generateThrows(out, ctor.getExceptionTypes());
266:
267: out.println("{");
268: out.pushDepth();
269:
270: out.print("super(");
271:
272: for (int i = 0; i < paramTypes.length; i++) {
273: if (i != 0)
274: out.print(", ");
275:
276: out.print("a" + i);
277: }
278: out.println(");");
279:
280: HashMap map = new HashMap();
281: for (BusinessMethodGenerator method : _businessMethods) {
282: method.generateConstructorTop(out, map);
283: }
284:
285: out.popDepth();
286: out.println("}");
287: }
288:
289: protected void generateThrows(JavaWriter out, Class[] exnCls)
290: throws IOException {
291: if (exnCls.length == 0)
292: return;
293:
294: out.print(" throws ");
295:
296: for (int i = 0; i < exnCls.length; i++) {
297: if (i != 0)
298: out.print(", ");
299:
300: out.printClass(exnCls[i]);
301: }
302: }
303: }
|