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.amber.field;
031:
032: import com.caucho.amber.manager.AmberPersistenceUnit;
033: import com.caucho.amber.table.Column;
034: import com.caucho.amber.type.*;
035: import com.caucho.config.ConfigException;
036: import com.caucho.java.JavaWriter;
037: import com.caucho.log.Log;
038: import com.caucho.util.CharBuffer;
039: import com.caucho.util.L10N;
040:
041: import java.io.IOException;
042: import java.sql.ResultSet;
043: import java.sql.SQLException;
044: import java.util.ArrayList;
045: import java.util.HashMap;
046: import java.util.HashSet;
047: import java.util.Map;
048: import java.util.logging.Logger;
049:
050: /**
051: * Configuration for a bean's field
052: */
053: public class Id {
054: private static final L10N L = new L10N(Id.class);
055: protected static final Logger log = Log.open(Id.class);
056:
057: private RelatedType _ownerType;
058:
059: private ArrayList<IdField> _keys = new ArrayList<IdField>();
060: private ArrayList<Column> _columns = new ArrayList<Column>();
061:
062: public Id(RelatedType ownerType, ArrayList<IdField> keys) {
063: _ownerType = ownerType;
064:
065: for (IdField key : keys) {
066: addKey(key);
067: }
068: }
069:
070: protected Id(RelatedType ownerType) {
071: _ownerType = ownerType;
072: }
073:
074: public Id(RelatedType ownerType, IdField key) {
075: _ownerType = ownerType;
076:
077: if (key instanceof EmbeddedIdField)
078: throw new IllegalArgumentException();
079:
080: // ejb/0623
081: addKey(key);
082: }
083:
084: /**
085: * Adds a new field to the id.
086: */
087: protected void addKey(IdField key) {
088: _keys.add(key);
089: // ejb/0a04
090: // Collections.sort(_keys, new AmberFieldCompare());
091:
092: // jpa/0ge2
093: if (_ownerType instanceof MappedSuperclassType)
094: return;
095:
096: // jpa/0gg0
097: if (_ownerType.isAbstractClass())
098: return;
099:
100: _columns.addAll(key.getColumns());
101: // Collections.sort(_columns, new ColumnCompare());
102:
103: for (Column column : key.getColumns()) {
104: _ownerType.getTable().addIdColumn(column);
105: }
106: }
107:
108: private static ArrayList<IdField> createField(IdField field) {
109: ArrayList<IdField> fields = new ArrayList<IdField>();
110: fields.add(field);
111: return fields;
112: }
113:
114: /**
115: * Returns the owner type.
116: */
117: public RelatedType getOwnerType() {
118: return _ownerType;
119: }
120:
121: /**
122: * Returns all the column.
123: */
124: public ArrayList<Column> getColumns() {
125: return _columns;
126: }
127:
128: /**
129: * Returns all the keys.
130: */
131: public ArrayList<IdField> getKeys() {
132: return _keys;
133: }
134:
135: /**
136: * Returns all the keys.
137: */
138: public int getKeyCount() {
139: return _columns.size();
140: }
141:
142: /**
143: * Returns the keys.
144: */
145: public IdField getKey() {
146: return _keys.get(0);
147: }
148:
149: /**
150: * Returns the foreign type.
151: */
152: public String getForeignTypeName() {
153: return _keys.get(0).getForeignTypeName();
154: }
155:
156: public boolean isIdentityGenerator() {
157: return _keys.size() == 1
158: && "identity".equals(_keys.get(0).getGenerator());
159: }
160:
161: /**
162: * Initialize the id.
163: */
164: public void init() throws ConfigException {
165: }
166:
167: /**
168: * Generates any prologue.
169: */
170: public void generatePrologue(JavaWriter out,
171: HashSet<Object> completedSet, String name)
172: throws IOException {
173: }
174:
175: /**
176: * Generates any prologue.
177: */
178: public void generatePrologue(JavaWriter out,
179: HashSet<Object> completedSet) throws IOException {
180: for (int i = 0; i < _keys.size(); i++)
181: _keys.get(i).generatePrologue(out, completedSet);
182: }
183:
184: /**
185: * Returns the foreign type.
186: */
187: public int generateLoadForeign(JavaWriter out, String rs,
188: String indexVar, int index) throws IOException {
189: return generateLoadForeign(out, rs, indexVar, index,
190: getForeignTypeName().replace('.', '_'));
191: }
192:
193: /**
194: * Returns the foreign type.
195: */
196: public int generateLoadForeign(JavaWriter out, String rs,
197: String indexVar, int index, String name) throws IOException {
198: if (_keys.size() > 1)
199: throw new UnsupportedOperationException();
200:
201: return _keys.get(0).generateLoadForeign(out, rs, indexVar,
202: index, name);
203: }
204:
205: /**
206: * Generates code to copy to an object.
207: */
208: public void generateCopy(JavaWriter out, String dest, String source)
209: throws IOException {
210: ArrayList<IdField> keys = getKeys();
211:
212: for (int i = 0; i < keys.size(); i++) {
213: IdField key = keys.get(i);
214:
215: out.println(key.generateSet(dest, key.generateGet(source))
216: + ";");
217: }
218: }
219:
220: //
221: // SQL generation
222: //
223:
224: /**
225: * Generates the select clause.
226: */
227: public String generateSelect(String id) {
228: return getKey().generateSelect(id);
229: }
230:
231: /**
232: * Generates the JPA QL select clause.
233: */
234: public String generateJavaSelect(String id) {
235: return getKey().generateJavaSelect(id);
236: }
237:
238: /**
239: * Generates the select clause.
240: */
241: public String generateLoadSelect(String id) {
242: return null;
243: }
244:
245: /**
246: * Returns the key for the value
247: */
248: public String generateGetProperty(String value) {
249: return getKey().generateGet(value);
250: }
251:
252: /**
253: * Returns the key for the value
254: */
255: public String generateGetProxyKey(String value) {
256: return "((" + getForeignTypeName() + ") " + value
257: + ".getPrimaryKey())";
258: }
259:
260: /**
261: * Generates loading cache
262: */
263: public void generateLoadFromObject(JavaWriter out, String obj)
264: throws IOException {
265: ArrayList<IdField> keys = getKeys();
266:
267: for (int i = 0; i < keys.size(); i++) {
268: keys.get(i).generateLoadFromObject(out, obj);
269: }
270: }
271:
272: /**
273: * Generates loading cache
274: */
275: public void generateSet(JavaWriter out, String obj)
276: throws IOException {
277: IdField key = getKey();
278:
279: key.generateSet(out, key.toValue(obj));
280: // key.generateSet(out, key.getColumn().getType().generateCastFromObject(obj));
281: }
282:
283: /**
284: * Generates loading cache
285: */
286: public void generateUpdateFromObject(JavaWriter out, String obj)
287: throws IOException {
288: ArrayList<IdField> keys = getKeys();
289:
290: for (int i = 0; i < keys.size(); i++) {
291: keys.get(i).generateUpdateFromObject(out, obj);
292: }
293: }
294:
295: /**
296: * Generates the where clause.
297: */
298: public String generateMatchArgWhere(String id) {
299: CharBuffer cb = new CharBuffer();
300:
301: boolean isFirst = true;
302:
303: for (IdField field : getKeys()) {
304: for (Column column : field.getColumns()) {
305: if (!isFirst)
306: cb.append(" and ");
307: isFirst = false;
308:
309: cb.append(column.generateMatchArgWhere(id));
310: }
311: }
312:
313: return cb.toString();
314: }
315:
316: /**
317: * Generates the where clause.
318: */
319: public String generateRawWhere(String id) {
320: ArrayList<IdField> keys = getKeys();
321:
322: CharBuffer cb = CharBuffer.allocate();
323:
324: for (int i = 0; i < keys.size(); i++) {
325: if (i != 0)
326: cb.append(" and ");
327:
328: cb.append(keys.get(i).generateRawWhere(id));
329: }
330:
331: return cb.close();
332: }
333:
334: /**
335: * Generates the where clause.
336: */
337: public String generateCreateTableSQL(AmberPersistenceUnit manager) {
338: String sql = getKey().generateCreateTableSQL(manager);
339:
340: if (getKey().getGenerator() != null)
341: return sql + " PRIMARY KEY auto_increment";
342: else
343: return sql + " PRIMARY KEY";
344: }
345:
346: /**
347: * Generates the set clause.
348: */
349: public void generateSetKey(JavaWriter out, String pstmt,
350: String index, String keyObject) throws IOException {
351: IdField key = getKey();
352:
353: key.getType().generateSet(out, pstmt, index, keyObject);
354: }
355:
356: /**
357: * Generates the set clause.
358: */
359: public void generateSet(JavaWriter out, String pstmt, String index,
360: String value) throws IOException {
361: ArrayList<IdField> keys = getKeys();
362:
363: for (int i = 0; i < keys.size(); i++) {
364: keys.get(i).generateSet(out, pstmt, index, value);
365: }
366: }
367:
368: /**
369: * Generates the set clause.
370: */
371: public void generateSet(JavaWriter out, String pstmt, String index)
372: throws IOException {
373: ArrayList<IdField> keys = getKeys();
374:
375: for (int i = 0; i < keys.size(); i++) {
376: keys.get(i).generateSet(out, pstmt, index);
377: }
378: }
379:
380: /**
381: * Generates the set clause.
382: */
383: /*
384: public String generateInsert()
385: {
386: String value = null;
387:
388: ArrayList<IdField> keys = getKeys();
389:
390: for (int i = 0; i < keys.size(); i++) {
391: String next = keys.get(i).generateInsert();
392:
393: if (value == null)
394: value = next;
395: else if (next == null) {
396: }
397: else
398: value += ", " + next;
399: }
400:
401: return value;
402: }
403: */
404:
405: /**
406: * Generates the set clause.
407: */
408: public void generateSetInsert(JavaWriter out, String pstmt,
409: String index) throws IOException {
410: ArrayList<IdField> keys = getKeys();
411:
412: for (int i = 0; i < keys.size(); i++) {
413: keys.get(i).generateSetInsert(out, pstmt, index);
414: }
415: }
416:
417: /**
418: * Generates code to convert to the type from the object.
419: */
420: public String generateCastFromObject(String value) {
421: return value;
422: }
423:
424: /**
425: * Generates code for a match.
426: */
427: public void generateMatch(JavaWriter out, String key)
428: throws IOException {
429: IdField id = getKeys().get(0);
430:
431: out.println("return ("
432: + id.generateEquals(id.generateSuperGetter(), id
433: .toValue(key)) + ");");
434: }
435:
436: /**
437: * Generates code to test the equals.
438: */
439: public String generateEquals(String leftBase, String value) {
440: ArrayList<IdField> keys = getKeys();
441:
442: String eq = "(";
443:
444: for (int i = 0; i < keys.size(); i++) {
445: IdField key = keys.get(i);
446:
447: if (i != 0)
448: eq += " && ";
449:
450: eq += key.generateEquals(leftBase, value);
451: }
452:
453: return eq + ")";
454: }
455:
456: /**
457: * Generates the set clause.
458: */
459: public void generateCheckCreateKey(JavaWriter out)
460: throws IOException {
461: ArrayList<IdField> keys = getKeys();
462:
463: for (int i = 0; i < keys.size(); i++) {
464: keys.get(i).generateCheckCreateKey(out);
465: }
466: }
467:
468: /**
469: * Generates the set clause.
470: */
471: public void generateSetGeneratedKeys(JavaWriter out, String pstmt)
472: throws IOException {
473: ArrayList<IdField> keys = getKeys();
474:
475: for (int i = 0; i < keys.size(); i++) {
476: keys.get(i).generateSetGeneratedKeys(out, pstmt);
477: }
478: }
479:
480: /**
481: * Returns the embedded id field
482: */
483: public EmbeddedIdField getEmbeddedIdField() {
484: return null;
485: }
486:
487: /**
488: * Returns true if this is an @EmbeddedId
489: */
490: public boolean isEmbeddedId() {
491: return false;
492: }
493:
494: /**
495: * Generates code to convert to the object.
496: */
497: public String toObject(String value) {
498: return getKey().toObject(value);
499: }
500:
501: /**
502: * Generates code to convert to the object.
503: */
504: public Object toObjectKey(long value) {
505: // return getColumn().toObjectKey(value);
506: return new Long(value);
507: }
508:
509: /**
510: * Generates code to convert to the object.
511: */
512: public Object getObject(ResultSet rs, int index)
513: throws SQLException {
514: return null;
515: }
516: }
|