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.gen.*;
034: import com.caucho.amber.field.IdField;
035: import com.caucho.amber.type.EntityType;
036: import com.caucho.config.ConfigException;
037: import com.caucho.ejb.cfg.*;
038: import com.caucho.ejb.ql.EjbSelectQuery;
039: import com.caucho.java.JavaWriter;
040: import com.caucho.java.gen.BaseMethod;
041: import com.caucho.util.L10N;
042:
043: import java.io.IOException;
044: import java.util.ArrayList;
045: import java.util.Collections;
046: import java.lang.reflect.*;
047:
048: /**
049: * Generates the code for a query
050: */
051: abstract public class AbstractQueryMethod extends BaseMethod {
052: private static final L10N L = new L10N(AbstractQueryMethod.class);
053:
054: private ApiMethod _method;
055: private EjbEntityBean _bean;
056: private EjbSelectQuery _query;
057: private boolean _queryLoadsBean = true;
058:
059: protected AbstractQueryMethod(EjbEntityBean bean, ApiMethod method,
060: EjbSelectQuery query) throws ConfigException {
061: super (method.getMethod());
062:
063: _bean = bean;
064: _query = query;
065: _method = method;
066:
067: /*
068: EjbConfig ejbConfig = beanType.getConfig();
069:
070: AmberPersistenceUnit amberManager = beanType.getConfig().getEJBManager().getAmberManager();
071: */
072: }
073:
074: /**
075: * Sets the query-loads-bean propery.
076: */
077: public void setQueryLoadsBean(boolean queryLoadsBean) {
078: _queryLoadsBean = queryLoadsBean;
079: }
080:
081: /**
082: * Gets the parameter types
083: */
084: public Class[] getParameterTypes() {
085: return _method.getParameterTypes();
086: }
087:
088: /**
089: * Gets the return type.
090: */
091: public Class getReturnType() {
092: return _method.getReturnType();
093: }
094:
095: protected String generateBeanId() {
096: return "bean.__caucho_getPrimaryKey()";
097: }
098:
099: void generatePrepareQuery(JavaWriter out, String[] args)
100: throws IOException {
101: out.println("com.caucho.amber.AmberQuery query;");
102:
103: out.print("query = trans.getAmberConnection().prepareQuery(\"");
104: out.print(_query.toAmberQuery(args));
105: out.println("\");");
106:
107: int len = args.length;
108:
109: if (_query.getMaxArg() < len)
110: len = _query.getMaxArg();
111:
112: if (len > 0 || _query.getThisExpr() != null)
113: out.println("int index = 1;");
114:
115: Class[] paramTypes = getParameterTypes();
116:
117: for (int i = 0; i < len; i++) {
118: generateSetParameter(out, paramTypes[i], args[i]);
119: }
120:
121: if (_query.getThisExpr() != null)
122: generateSetThis(out, _bean, "query");
123:
124: if (_query.getOffsetValue() > 0)
125: out.println("query.setFirstResult("
126: + _query.getOffsetValue() + ");");
127: else if (_query.getOffsetArg() > 0)
128: out.println("query.setFirstResult("
129: + args[_query.getOffsetArg() - 1] + ");");
130:
131: if (_query.getLimitValue() > 0)
132: out.println("query.setMaxResults(" + _query.getLimitValue()
133: + ");");
134: else if (_query.getLimitArg() > 0)
135: out.println("query.setMaxResults("
136: + args[_query.getLimitArg() - 1] + ");");
137:
138: if (!_queryLoadsBean)
139: out.println("query.setLoadOnQuery(false);");
140: }
141:
142: public static void generateSetThis(JavaWriter out,
143: EjbEntityBean bean, String query) throws IOException {
144: EntityType amberType = bean.getEntityType();
145:
146: ArrayList<IdField> keys = new ArrayList<IdField>();
147: keys.addAll(amberType.getId().getKeys());
148: Collections.sort(keys, new IdFieldCompare());
149:
150: for (IdField field : keys) {
151: field.generateSet(out, query + "", "index", "super");
152: }
153: }
154:
155: public void generateSetParameter(JavaWriter out, Class type,
156: String arg) throws IOException {
157: generateSetParameter(out, _bean.getConfig(), type, "query", arg);
158: }
159:
160: public static void generateSetParameter(JavaWriter out,
161: EjbConfig config, Class type, String query, String arg)
162: throws IOException {
163: if (type.getName().equals("boolean")) {
164: // printCheckNull(out, type, arg);
165:
166: out.println(query + ".setBoolean(index++, " + arg + ");");
167: } else if (type.getName().equals("byte")) {
168: // printCheckNull(index, type, expr);
169:
170: out.println(query + ".setInt(index++, " + arg + ");");
171: } else if (type.getName().equals("short")) {
172: // printCheckNull(index, type, expr);
173:
174: out.println(query + ".setInt(index++, " + arg + ");");
175: } else if (type.getName().equals("int")) {
176: // printCheckNull(index, type, expr);
177:
178: out.println(query + ".setInt(index++, " + arg + ");");
179: } else if (type.getName().equals("long")) {
180: // printCheckNull(index, type, expr);
181:
182: out.println(query + ".setLong(index++, " + arg + ");");
183: } else if (type.getName().equals("char")) {
184: // printCheckNull(index, type, expr);
185:
186: out.println(query + ".setString(index++, String.valueOf("
187: + arg + "));");
188: } else if (type.getName().equals("float")) {
189: // printCheckNull(index, type, expr);
190:
191: out.println(query + ".setFloat(index++, " + arg + ");");
192: } else if (type.getName().equals("double")) {
193: // printCheckNull(index, type, expr);
194:
195: out.println(query + ".setDouble(index++, " + arg + ");");
196: } else if (java.sql.Timestamp.class.isAssignableFrom(type)) {
197: out.println(query + ".setTimestamp(index++, " + arg + ");");
198: } else if (java.sql.Date.class.isAssignableFrom(type))
199: out.println(query + ".setDate(index++, " + arg + ");");
200: else if (java.sql.Time.class.isAssignableFrom(type))
201: out.println(query + ".setTime(index++, " + arg + ");");
202: else if (java.util.Date.class.isAssignableFrom(type)) {
203: out.println("{");
204: out.println(" java.util.Date _caucho_tmp_date = " + arg
205: + ";");
206: out.println(" if (_caucho_tmp_date == null)");
207: out.println(" " + query
208: + ".setNull(index++, java.sql.Types.TIMESTAMP);");
209: out.println(" else");
210: out
211: .println(" "
212: + query
213: + ".setTimestamp(index++, new java.sql.Timestamp(_caucho_tmp_date.getTime()));");
214: out.println("}");
215: } else if (Boolean.class.equals(type)) {
216: out.println("if (" + arg + " == null)");
217: out.println(" " + query
218: + ".setNull(index++, java.sql.Types.BIT);");
219: out.println("else");
220: out.println(" " + query + ".setBoolean(index++, " + arg
221: + ".booleanValue());");
222: } else if (Character.class.equals(type)) {
223: out.println("if (" + arg + " == null)");
224: out.println(" " + query
225: + ".setNull(index++, java.sql.Types.VARCHAR);");
226: out.println("else");
227: out.println(" " + query + ".setString(index++, " + arg
228: + ".toString());");
229: } else if (String.class.equals(type)) {
230: out.println(" " + query + ".setString(index++, " + arg
231: + ");");
232: } else if (Byte.class.equals(type)) {
233: out.println("if (" + arg + " == null)");
234: out.println(" " + query
235: + ".setNull(index++, java.sql.Types.TINYINT);");
236: out.println("else");
237: out.println(" " + query + ".setInt(index++, " + arg
238: + ".byteValue());");
239: } else if (Short.class.equals(type)) {
240: out.println("if (" + arg + " == null)");
241: out.println(" " + query
242: + ".setNull(index++, java.sql.Types.SMALLINT);");
243: out.println("else");
244: out.println(" " + query + ".setInt(index++, " + arg
245: + ".shortValue());");
246: } else if (Integer.class.equals(type)) {
247: out.println("if (" + arg + " == null)");
248: out.println(" " + query
249: + ".setNull(index++, java.sql.Types.INTEGER);");
250: out.println("else");
251: out.println(" " + query + ".setInt(index++, " + arg
252: + ".intValue());");
253: } else if (Long.class.equals(type)) {
254: out.println("if (" + arg + " == null)");
255: out.println(" " + query
256: + ".setNull(index++, java.sql.Types.BIGINT);");
257: out.println("else");
258: out.println(" " + query + ".setLong(index++, " + arg
259: + ".longValue());");
260: } else if (Float.class.equals(type)) {
261: out.println("if (" + arg + " == null)");
262: out.println(" " + query
263: + ".setNull(index++, java.sql.Types.REAL);");
264: out.println("else");
265: out.println(" " + query + ".setDouble(index++, " + arg
266: + ".floatValue());");
267: } else if (Double.class.equals(type)) {
268: out.println("if (" + arg + " == null)");
269: out.println(" " + query
270: + ".setNull(index++, java.sql.Types.DOUBLE);");
271: out.println("else");
272: out.println(" " + query + ".setDouble(index++, " + arg
273: + ".doubleValue());");
274: } else if (java.math.BigDecimal.class.equals(type)) {
275: out.println("if (" + arg + " == null)");
276: out.println(" " + query
277: + ".setNull(index++, java.sql.Types.NUMERIC);");
278: out.println("else");
279: out.println(" " + query + ".setBigDecimal(index++, " + arg
280: + ");");
281: } else if (byte[].class.equals(type)) {
282: out.println("if (" + arg + " == null)");
283: out.println(" " + query
284: + ".setNull(index++, java.sql.Types.VARBINARY);");
285: out.println("else {");
286: out.println(" byte []bArray = (byte []) " + arg + ";");
287: out
288: .println(" "
289: + query
290: + ".setBinaryStream(index++, new java.io.ByteArrayInputStream(bArray), bArray.length);");
291: out.println("}");
292:
293: // XXX; fixing oracle issues
294: // out.println(" " + query + ".setBytes(index++, (byte []) " + arg + ");");
295: }
296: /*
297: else if (Serializable.class.isAssignableFrom(type)) {
298: out.println("if (" + arg + " == null)");
299: out.println(" " + query + ".setNull(index++, 0);");
300: out.println("else");
301: out.println(" " + query + ".setBytes(index++, _caucho_serialize(" + arg + "));");
302: hasSerialization = true;
303: }
304: */
305: else if (javax.ejb.EJBLocalObject.class.isAssignableFrom(type)) {
306: EjbEntityBean bean = config.findEntityByLocal(type);
307:
308: if (bean == null)
309: throw new IllegalStateException(L.l(
310: "can't find bean for {0}", type.getName()));
311:
312: EntityType amberType = bean.getEntityType();
313:
314: ArrayList<IdField> keys = new ArrayList<IdField>();
315: keys.addAll(amberType.getId().getKeys());
316: Collections.sort(keys, new IdFieldCompare());
317:
318: String var = "_expr" + out.generateId();
319: out.printClass(type);
320: out.println(" " + var + " = " + arg + ";");
321:
322: out.println("if (" + var + " != null) {");
323: out.pushDepth();
324:
325: for (IdField field : keys) {
326: field.generateSet(out, query + "", "index", arg);
327: }
328:
329: out.popDepth();
330: out.println("} else {");
331: out.pushDepth();
332:
333: for (IdField field : keys) {
334: field.generateSet(out, query + "", "index", null);
335: }
336:
337: out.popDepth();
338: out.println("}");
339: } else {
340: Field[] fields = type.getFields();
341:
342: String var = "_expr" + out.generateId();
343: out.printClass(type);
344: out.println(" " + var + " = " + arg + ";");
345:
346: out.println("if (" + var + " != null) {");
347: out.pushDepth();
348: for (Field field : fields) {
349: generateSetParameter(out, config, field.getType(),
350: query, arg + "." + field.getName());
351: }
352: out.popDepth();
353: out.println("} else {");
354: out.pushDepth();
355:
356: // XXX:
357: for (int i = 0; i < fields.length; i++) {
358: out.println(query + ".setNull(index++, 0);");
359: }
360:
361: out.popDepth();
362: out.println("}");
363: }
364: }
365: }
|