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.ejb.*;
038: import java.io.IOException;
039: import java.lang.reflect.*;
040: import java.util.*;
041:
042: /**
043: * Represents a public interface to a stateful bean, e.g. a stateful view
044: */
045: abstract public class StatefulView extends View {
046: private static final L10N L = new L10N(StatefulView.class);
047:
048: private StatefulGenerator _sessionBean;
049:
050: private ArrayList<StatefulMethod> _businessMethods = new ArrayList<StatefulMethod>();
051:
052: public StatefulView(StatefulGenerator bean, ApiClass api) {
053: super (bean, api);
054:
055: _sessionBean = bean;
056: }
057:
058: public StatefulGenerator getSessionBean() {
059: return _sessionBean;
060: }
061:
062: public String getContextClassName() {
063: return getSessionBean().getClassName();
064: }
065:
066: abstract protected String getViewClassName();
067:
068: /**
069: * Returns the introspected methods
070: */
071: public ArrayList<? extends BusinessMethodGenerator> getMethods() {
072: return _businessMethods;
073: }
074:
075: /**
076: * Introspects the APIs methods, producing a business method for
077: * each.
078: */
079: @Override
080: public void introspect() {
081: ApiClass implClass = getEjbClass();
082: ApiClass apiClass = getApi();
083:
084: for (ApiMethod apiMethod : apiClass.getMethods()) {
085: if (apiMethod.getDeclaringClass().equals(Object.class))
086: continue;
087: if (apiMethod.getDeclaringClass().getName().startsWith(
088: "javax.ejb.")
089: && !apiMethod.getName().equals("remove"))
090: continue;
091:
092: if (apiMethod.getName().startsWith("ejb")) {
093: throw new ConfigException(
094: L
095: .l(
096: "{0}: '{1}' must not start with 'ejb'. The EJB spec reserves all methods starting with ejb.",
097: apiMethod.getDeclaringClass(),
098: apiMethod.getName()));
099: }
100:
101: int index = _businessMethods.size();
102:
103: StatefulMethod bizMethod = createMethod(apiMethod, index);
104:
105: if (bizMethod != null) {
106: bizMethod.introspect(bizMethod.getApiMethod(),
107: bizMethod.getImplMethod());
108:
109: _businessMethods.add(bizMethod);
110: }
111: }
112: }
113:
114: /**
115: * Generates code to create the provider
116: */
117: public void generateCreateProvider(JavaWriter out, String var)
118: throws IOException {
119: out.println();
120: out.println("if (" + var + " == " + getApi().getName()
121: + ".class)");
122: out.println(" return new " + getViewClassName()
123: + "(getStatefulServer());");
124: }
125:
126: /**
127: * Generates the view code.
128: */
129: public void generate(JavaWriter out) throws IOException {
130: out.println();
131: out.println("public static class " + getViewClassName());
132:
133: generateExtends(out);
134:
135: out.print(" implements " + getApi().getName());
136: out.println(", StatefulProvider");
137: out.println("{");
138: out.pushDepth();
139:
140: generateClassContent(out);
141:
142: out.popDepth();
143: out.println("}");
144: }
145:
146: protected void generateClassContent(JavaWriter out)
147: throws IOException {
148: out.println("private StatefulContext _context;");
149: out.println("private StatefulServer _server;");
150: out.println("private " + getEjbClass().getName() + " _bean;");
151:
152: generateBusinessPrologue(out);
153:
154: out.println();
155: out.println(getViewClassName() + "(StatefulServer server)");
156: out.println("{");
157: out.pushDepth();
158:
159: generateSuper(out, "server");
160:
161: out.println("_server = server;");
162:
163: out.popDepth();
164: out.println("}");
165:
166: out.println();
167: out.println("public " + getViewClassName()
168: + "(StatefulServer server, ConfigContext env)");
169: out.println("{");
170: out.pushDepth();
171:
172: generateSuper(out, "server");
173: out.println("_server = server;");
174: out.println("_bean = new " + getEjbClass().getName() + "();");
175: generateBusinessConstructor(out);
176:
177: out.popDepth();
178: out.println("}");
179:
180: generateSessionProvider(out);
181:
182: out.println();
183: out.println("public " + getViewClassName()
184: + "(StatefulServer server, " + getEjbClass().getName()
185: + " bean)");
186: out.println("{");
187: generateSuper(out, "server");
188: out.println(" _server = server;");
189: out.println(" _bean = bean;");
190: generateBusinessConstructor(out);
191: out.println("}");
192:
193: out.println();
194: out.println("public StatefulServer getStatefulServer()");
195: out.println("{");
196: out.println(" return _server;");
197: out.println("}");
198: out.println();
199:
200: out.println();
201: out
202: .println("void __caucho_setContext(StatefulContext context)");
203: out.println("{");
204: out.println(" _context = context;");
205: out.println("}");
206:
207: generateBusinessMethods(out);
208: }
209:
210: protected void generateSessionProvider(JavaWriter out)
211: throws IOException {
212: out.println();
213: out
214: .println("public Object __caucho_createNew(ConfigContext env)");
215: out.println("{");
216: out.println(" " + getViewClassName() + " bean" + " = new "
217: + getViewClassName() + "(_server, env);");
218: out.println(" _server.initInstance(bean._bean, env);");
219: out.println(" return bean;");
220: out.println("}");
221: }
222:
223: protected StatefulMethod createMethod(ApiMethod apiMethod, int index) {
224: ApiMethod implMethod = findImplMethod(apiMethod);
225:
226: if (implMethod == null)
227: return null;
228:
229: StatefulMethod bizMethod = new StatefulMethod(this , apiMethod,
230: implMethod.getMethod(), index);
231:
232: return bizMethod;
233: }
234:
235: protected void generateSuper(JavaWriter out, String serverVar)
236: throws IOException {
237: }
238:
239: protected void generateExtends(JavaWriter out) throws IOException {
240: }
241:
242: protected ApiMethod findImplMethod(ApiMethod apiMethod) {
243: ApiMethod implMethod = getEjbClass().getMethod(apiMethod);
244:
245: if (implMethod != null)
246: return implMethod;
247:
248: throw new ConfigException(
249: L
250: .l(
251: "'{0}' method '{1}' has no corresponding implementation in '{2}'",
252: apiMethod.getMethod()
253: .getDeclaringClass()
254: .getSimpleName(),
255: getFullMethodName(apiMethod),
256: getEjbClass().getName()));
257: }
258: }
|