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.expr.AmberExpr;
033: import com.caucho.amber.expr.PathExpr;
034: import com.caucho.amber.query.QueryParser;
035: import com.caucho.amber.table.Column;
036: import com.caucho.amber.table.ForeignColumn;
037: import com.caucho.amber.table.LinkColumns;
038: import com.caucho.amber.type.RelatedType;
039: import com.caucho.amber.type.Type;
040: import com.caucho.config.ConfigException;
041: import com.caucho.java.JavaWriter;
042: import com.caucho.log.Log;
043: import com.caucho.util.L10N;
044:
045: import javax.persistence.CascadeType;
046: import java.io.IOException;
047: import java.util.logging.Logger;
048:
049: /**
050: * Configuration for a bean's field
051: */
052: public class CollectionField extends CascadableField {
053: private static final L10N L = new L10N(CollectionField.class);
054: protected static final Logger log = Log.open(CollectionField.class);
055:
056: private Type _targetType;
057:
058: private LinkColumns _linkColumns;
059:
060: private String _table;
061:
062: public CollectionField(RelatedType relatedType, String name,
063: CascadeType[] cascadeTypes) throws ConfigException {
064: super (relatedType, name, cascadeTypes);
065: }
066:
067: public CollectionField(RelatedType relatedType) {
068: super (relatedType);
069: }
070:
071: /**
072: * Sets the collection table.
073: */
074: public void setTable(String table) {
075: _table = table;
076: }
077:
078: /**
079: * Gets the collection table.
080: */
081: public String getTableName() {
082: return _table;
083: }
084:
085: /**
086: * Sets the target type.
087: */
088: public void setType(Type targetType) {
089: _targetType = targetType;
090: }
091:
092: /**
093: * Returns the target type.
094: */
095: public Type getTargetType() {
096: return _targetType;
097: }
098:
099: /**
100: * Sets the key columns.
101: */
102: public void setLinkColumns(LinkColumns linkColumns) {
103: _linkColumns = linkColumns;
104: }
105:
106: /**
107: * Gets the key columns.
108: */
109: public LinkColumns getLinkColumns() {
110: return _linkColumns;
111: }
112:
113: /**
114: * Generates the (pre) cascade operation from
115: * parent to this child. This field will only
116: * be cascaded first if the operation can be
117: * performed with no risk to break FK constraints.
118: */
119: public void generatePreCascade(JavaWriter out, String aConn,
120: CascadeType cascadeType) throws IOException {
121: if (isCascade(cascadeType)) {
122:
123: String getter = "_caucho_field_" + getGetterName(); // generateSuperGetter();
124:
125: out.println("if (" + getter + " != null) {");
126: out.pushDepth();
127:
128: out.println("for (Object o : " + getter + ") {");
129: out.pushDepth();
130:
131: // jpa/1622
132: if (cascadeType == CascadeType.REMOVE) {
133: // jpa/0i60
134: out
135: .println("com.caucho.amber.entity.Entity child = (com.caucho.amber.entity.Entity) o;");
136: out.println();
137:
138: out
139: .println("if (! child.__caucho_getEntityState().isTransactional())");
140: out.println(" continue;");
141: out.println();
142: }
143: // else {
144: // out.println("if (com.caucho.amber.entity.EntityState.P_DELETING.ordinal() <= child.__caucho_getEntityState().ordinal())");
145: // out.println(" continue;");
146: // }
147:
148: out.print(aConn + ".");
149:
150: switch (cascadeType) {
151: case PERSIST:
152: out.print("persistFromCascade");
153: break;
154:
155: case MERGE:
156: out.print("merge");
157: break;
158:
159: case REMOVE:
160: out.print("remove");
161: break;
162:
163: case REFRESH:
164: out.print("refresh");
165: break;
166: }
167:
168: out.println("(o);");
169:
170: out.popDepth();
171: out.println("}");
172:
173: out.popDepth();
174: out.println("}");
175: }
176: }
177:
178: /**
179: * Generates the (post) cascade operation from
180: * parent to this child. This field will only
181: * be cascaded first if the operation can be
182: * performed with no risk to break FK constraints.
183: */
184: public void generatePostCascade(JavaWriter out, String aConn,
185: CascadeType cascadeType) throws IOException {
186: }
187:
188: /**
189: * Generates the set clause.
190: */
191: public void generateSet(JavaWriter out, String pstmt, String obj,
192: String index) throws IOException {
193: }
194:
195: /**
196: * Generates loading cache
197: */
198: public void generateUpdate(JavaWriter out, String mask,
199: String pstmt, String index) throws IOException {
200: String maskVar = mask + "_" + (getIndex() / 64);
201: long maskValue = (1L << (getIndex() % 64));
202:
203: out.println();
204: out.println("if ((" + maskVar + " & " + maskValue
205: + "L) != 0) {");
206: out.pushDepth();
207:
208: generateSet(out, pstmt, index);
209:
210: out.popDepth();
211: out.println("}");
212: }
213:
214: /**
215: * Updates the cached copy.
216: */
217: public void generateCopyUpdateObject(JavaWriter out, String dst,
218: String src, int updateIndex) throws IOException {
219: }
220:
221: /**
222: * Generates the select clause.
223: */
224: public String generateLoadSelect(String id) {
225: return null;
226: }
227:
228: /**
229: * Generates the target select.
230: */
231: public String generateTargetSelect(String id) {
232: throw new UnsupportedOperationException(getClass().getName());
233: }
234:
235: /**
236: * Creates the expression for the field.
237: */
238: public AmberExpr createExpr(QueryParser parser, PathExpr parent) {
239: throw new UnsupportedOperationException(getClass().getName());
240: }
241:
242: /**
243: * Generates the linking for a join
244: */
245: public String generateJoin(String sourceTable, String targetTable) {
246: return _linkColumns.generateJoin(sourceTable, targetTable);
247: }
248:
249: /**
250: * Returns the source column for a given target key.
251: */
252: public ForeignColumn getSourceColumn(Column key) {
253: return _linkColumns.getSourceColumn(key);
254: }
255: }
|