KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ejb > cfg > CmrOneToMany


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.ejb.cfg;
31
32 import com.caucho.amber.field.AmberField;
33 import com.caucho.amber.field.EntityOneToManyField;
34 import com.caucho.amber.field.Id;
35 import com.caucho.amber.manager.AmberPersistenceUnit;
36 import com.caucho.amber.table.Column;
37 import com.caucho.amber.table.ForeignColumn;
38 import com.caucho.amber.table.LinkColumns;
39 import com.caucho.amber.type.EntityType;
40 import com.caucho.bytecode.JClass;
41 import com.caucho.bytecode.JMethod;
42 import com.caucho.config.ConfigException;
43 import com.caucho.ejb.ql.QLParser;
44 import com.caucho.java.JavaWriter;
45 import com.caucho.util.L10N;
46
47 import java.io.IOException JavaDoc;
48 import java.util.ArrayList JavaDoc;
49
50 /**
51  * one-to-many relation
52  */

53 public class CmrOneToMany extends CmrRelation {
54   private static final L10N L = new L10N(CmrOneToMany.class);
55
56   private EjbEntityBean _targetBean;
57   private String JavaDoc _targetField;
58
59   private ArrayList JavaDoc<String JavaDoc> _orderByFields;
60   private ArrayList JavaDoc<Boolean JavaDoc> _orderByAscending;
61
62   private SqlRelation []_sqlColumns;
63
64   private EntityOneToManyField _amberOneToMany;
65
66   /**
67    * Creates a new cmp-relation
68    */

69   public CmrOneToMany(EjbEntityBean entityBean,
70                       String JavaDoc fieldName,
71                       EjbEntityBean targetBean,
72                       String JavaDoc targetField)
73     throws ConfigException
74   {
75     super(entityBean, fieldName);
76
77     _targetBean = targetBean;
78     _targetField = targetField;
79   }
80
81   /**
82    * Returns the target bean
83    */

84   public EjbEntityBean getTargetBean()
85   {
86     return _targetBean;
87   }
88
89   /**
90    * Returns the target type.
91    */

92   public JClass getTargetType()
93   {
94     return _targetBean.getLocal();
95   }
96
97   /**
98    * Sets the column.
99    */

100   public void setSQLColumns(SqlRelation []columns)
101   {
102     _sqlColumns = columns;
103   }
104
105   /**
106    * Gets the column.
107    */

108   public SqlRelation []getSQLColumns()
109   {
110     return _sqlColumns;
111   }
112
113   /**
114    * Sets the order by.
115    */

116   public void setOrderBy(String JavaDoc orderBySQL)
117     throws ConfigException
118   {
119     if (orderBySQL != null) {
120       ArrayList JavaDoc<String JavaDoc> fields = new ArrayList JavaDoc<String JavaDoc>();
121       ArrayList JavaDoc<Boolean JavaDoc> asc = new ArrayList JavaDoc<Boolean JavaDoc>();
122
123       QLParser.parseOrderBy(_targetBean, orderBySQL, fields, asc);
124
125       _orderByFields = fields;
126       _orderByAscending = asc;
127     }
128   }
129
130   /**
131    * The OneToMany is a collection.
132    */

133   public boolean isCollection()
134   {
135     return true;
136   }
137
138   /**
139    * Create any bean methods.
140    */

141   public EjbMethod createGetter(EjbView view,
142                                 JMethod apiMethod,
143                                 JMethod implMethod)
144     throws ConfigException
145   {
146     return new EjbOneToManyMethod(view, apiMethod, implMethod, this);
147   }
148
149   /**
150    * Creates the amber type.
151    */

152   public AmberField assembleAmber(EntityType type)
153     throws ConfigException
154   {
155     EntityOneToManyField oneToMany = new EntityOneToManyField(type, getName());
156
157     AmberPersistenceUnit manager = type.getPersistenceUnit();
158
159     EntityType targetType = _targetBean.getEntityType();
160     oneToMany.setType(targetType);
161
162     // if bi-directional, then other side handles it
163
// if (! (getTargetRelation() instanceof CmrManyToOne)) {
164

165     oneToMany.setOrderBy(_orderByFields, _orderByAscending);
166
167     _amberOneToMany = oneToMany;
168
169     return oneToMany;
170   }
171
172   /**
173    * Link amber.
174    */

175   public void linkAmber()
176     throws ConfigException
177   {
178     CmrManyToOne manyToOne = (CmrManyToOne) getTargetRelation();
179
180     _amberOneToMany.setSourceField(manyToOne.getAmberManyToOne());
181     _amberOneToMany.setLinkColumns(manyToOne.getAmberManyToOne().getLinkColumns());
182
183     _amberOneToMany.init();
184   }
185
186   /**
187    * Generates the destroy method.
188    */

189   public void generateAfterCommit(JavaWriter out)
190     throws IOException JavaDoc
191   {
192     if (getHasGetter())
193       out.println("__caucho_field_" + getName() + " = null;");
194   }
195
196   private LinkColumns calculateColumn(EntityType parentType,
197                                       EntityType childType,
198                                       String JavaDoc fieldName,
199                                       SqlRelation []sqlColumns)
200     throws ConfigException
201   {
202     Id id = parentType.getId();
203     ArrayList JavaDoc<Column> keys = new ArrayList JavaDoc<Column>(id.getColumns());
204     ArrayList JavaDoc<ForeignColumn> columns = new ArrayList JavaDoc();
205
206     // XXX: need to remove self from the keys if identifying
207
/*
208       for (int i = keys.size() - 1; i >= 0; i--) {
209       IdField key = keys.get(i);
210
211       if (key instanceof KeyManyToOneField) {
212       KeyManyToOneField manyToOne = (KeyManyToOneField) key;
213
214       if (manyToOne.getEntityType() == sourceType)
215       keys.remove(i);
216       }
217       }
218     */

219
220     if (_sqlColumns != null && _sqlColumns.length == keys.size()) {
221       for (int i = 0; i < keys.size(); i++) {
222         Column key = keys.get(i);
223
224         String JavaDoc sqlColumn = getColumn(_sqlColumns, key.getName());
225         ForeignColumn column =
226           childType.getTable().createForeignColumn(sqlColumn, key);
227
228         columns.add(column);
229       }
230     }
231     else if (_sqlColumns != null && _sqlColumns.length == 1) {
232       String JavaDoc baseSqlColumn = _sqlColumns[0].getSQLColumn();
233
234       for (Column key : keys) {
235         String JavaDoc sqlColumn;
236
237         sqlColumn = baseSqlColumn + "_" + key.getName();
238
239         ForeignColumn column =
240           childType.getTable().createForeignColumn(sqlColumn, key);
241         columns.add(column);
242       }
243     }
244     else if (_sqlColumns != null && _sqlColumns.length > 0) {
245       throw new IllegalStateException JavaDoc("Mismatched SQL columns");
246     }
247     else if (keys.size() == 1) {
248       Column key = keys.get(0);
249
250       String JavaDoc sqlColumn = CmpField.toSqlName(fieldName);
251
252       ForeignColumn column =
253         childType.getTable().createForeignColumn(sqlColumn, key);
254
255       columns.add(column);
256     }
257     else {
258       String JavaDoc baseSqlColumn = CmpField.toSqlName(fieldName);
259
260       for (Column key : keys) {
261         String JavaDoc sqlColumn = baseSqlColumn + "_" + key.getName();
262
263         ForeignColumn foreignColumn =
264           childType.getTable().createForeignColumn(sqlColumn, key);
265
266         columns.add(foreignColumn);
267       }
268     }
269
270     return new LinkColumns(childType.getTable(),
271                            parentType.getTable(),
272                            columns);
273   }
274
275   private String JavaDoc getColumn(SqlRelation []sqlColumns, String JavaDoc fieldName)
276     throws ConfigException
277   {
278     if (sqlColumns.length == 1)
279       return sqlColumns[0].getSQLColumn();
280
281     for (int i = 0; i < sqlColumns.length; i++) {
282       String JavaDoc ref = sqlColumns[i].getReferences();
283
284       if (ref == null)
285         throw new ConfigException(L.l("sql-column '{0}' needs a references attribute.",
286                                       sqlColumns[i].getSQLColumn()));
287
288       if (ref.equals(fieldName))
289         return sqlColumns[i].getSQLColumn();
290     }
291
292     throw new ConfigException(L.l("key '{0}' has no matching sql-column",
293                                   fieldName));
294   }
295 }
296
Popular Tags