KickJava   Java API By Example, From Geeks To Geeks.

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


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.DependentEntityOneToOneField;
34 import com.caucho.amber.field.EntityManyToOneField;
35 import com.caucho.amber.field.Id;
36 import com.caucho.amber.field.IdField;
37 import com.caucho.amber.field.KeyManyToOneField;
38 import com.caucho.amber.manager.AmberPersistenceUnit;
39 import com.caucho.amber.table.Column;
40 import com.caucho.amber.table.ForeignColumn;
41 import com.caucho.amber.table.LinkColumns;
42 import com.caucho.amber.type.EntityType;
43 import com.caucho.bytecode.JClass;
44 import com.caucho.bytecode.JMethod;
45 import com.caucho.config.ConfigException;
46 import com.caucho.util.L10N;
47 import com.caucho.util.Log;
48
49 import java.util.ArrayList JavaDoc;
50 import java.util.logging.Logger JavaDoc;
51
52 /**
53  * many-to-one relation
54  */

55 public class CmrManyToOne extends CmrRelation {
56   private static final L10N L = new L10N(CmrManyToOne.class);
57   private static final Logger JavaDoc log = Log.open(CmrManyToOne.class);
58
59   private final EjbEntityBean _targetBean;
60
61   private SqlRelation []_sqlColumns;
62
63   private EntityManyToOneField _amberManyToOne;
64   private DependentEntityOneToOneField _amberDependentOneToOne;
65
66   private boolean _isDependent;
67   private boolean _isSourceCascadeDelete;
68   private boolean _isTargetCascadeDelete;
69   
70   /**
71    * Creates a new cmp-relation
72    */

73   public CmrManyToOne(EjbEntityBean entityBean,
74               String JavaDoc fieldName,
75               EjbEntityBean targetBean)
76     throws ConfigException
77   {
78     super(entityBean, fieldName);
79
80     _targetBean = targetBean;
81
82     JMethod getter = getGetter();
83     
84     if (! getter.getReturnType().equals(_targetBean.getLocal()))
85       throw new ConfigException(L.l("{0}: '{1}' must return the local interface '{2}' of the EJB bean '{3}'.",
86                     entityBean.getEJBClass().getName(),
87                     getter.getFullName(),
88                     _targetBean.getLocal().getName(),
89                     _targetBean.getEJBName()));
90   }
91
92   /**
93    * Returns the target bean
94    */

95   public EjbEntityBean getTargetBean()
96   {
97     return _targetBean;
98   }
99
100   /**
101    * Returns the target type.
102    */

103   public JClass getTargetType()
104   {
105     return _targetBean.getLocal();
106   }
107
108   /**
109    * Sets the column.
110    */

111   public void setSQLColumns(SqlRelation []columns)
112   {
113     _sqlColumns = columns;
114   }
115
116   /**
117    * Gets the column.
118    */

119   public SqlRelation []getSQLColumns()
120   {
121     return _sqlColumns;
122   }
123
124   /**
125    * Set true for a dependent one-to-one
126    */

127   public void setDependent(boolean isDependent)
128   {
129     _isDependent = isDependent;
130   }
131
132   /**
133    * Set true for a cascade-delete many-to-one
134    */

135   public void setSourceCascadeDelete(boolean isCascadeDelete)
136   {
137     _isSourceCascadeDelete = isCascadeDelete;
138   }
139
140   /**
141    * Set true for a cascade-delete many-to-one
142    */

143   public void setTargetCascadeDelete(boolean isCascadeDelete)
144   {
145     _isTargetCascadeDelete = isCascadeDelete;
146   }
147
148   /**
149    * Return true for a cascade-delete many-to-one
150    */

151   public boolean isCascadeDelete()
152   {
153     return _isSourceCascadeDelete;
154   }
155
156   /**
157    * Returns the amber many-to-one.
158    */

159   public EntityManyToOneField getAmberManyToOne()
160   {
161       
162     if (_amberManyToOne == null) {
163       try {
164     EntityType sourceType = getEntity().getEntityType();
165     
166     _amberManyToOne = new EntityManyToOneField(sourceType, getName());
167
168     EntityType targetType = _targetBean.getEntityType();
169     _amberManyToOne.setType(targetType);
170
171     _amberManyToOne.setLinkColumns(calculateColumns(sourceType,
172                             targetType));
173
174     if (! _isDependent) {
175       _amberManyToOne.setSourceCascadeDelete(_isSourceCascadeDelete);
176       _amberManyToOne.setTargetCascadeDelete(_isTargetCascadeDelete);
177     }
178
179     _amberManyToOne.init();
180       } catch (RuntimeException JavaDoc e) {
181     throw e;
182       } catch (Exception JavaDoc e) {
183     throw new RuntimeException JavaDoc(e);
184       }
185     }
186       
187     return _amberManyToOne;
188   }
189
190   /**
191    * Returns the amber one-to-one.
192    */

193   public DependentEntityOneToOneField getAmberOneToOne()
194   {
195     return _amberDependentOneToOne;
196   }
197
198   /**
199    * Amber creating the id field.
200    */

201   public IdField createId(AmberPersistenceUnit amberPersistenceUnit, EntityType type)
202     throws ConfigException
203   {
204     String JavaDoc fieldName = getName();
205
206     EntityType sourceType = getEntity().getEntityType();
207     EntityType targetType = getTargetBean().getEntityType();
208
209     /*
210     columns.add(new ForeignColumn(sqlName, targetType.getId().getKeys().get(0)));
211     */

212
213     KeyManyToOneField keyField = new KeyManyToOneField(type, fieldName);
214     keyField.setType(targetType);
215     
216     keyField.setLinkColumns(calculateColumns(sourceType, targetType));
217
218     keyField.init();
219       
220     return keyField;
221   }
222
223   /**
224    * Creates the amber type.
225    */

226   public AmberField assembleAmber(EntityType type)
227     throws ConfigException
228   {
229     AmberPersistenceUnit manager = type.getPersistenceUnit();
230     EntityType targetType = getTargetBean().getEntityType();
231
232     if (_isDependent) {
233       DependentEntityOneToOneField oneToOne;
234       oneToOne = new DependentEntityOneToOneField(type, getName());
235
236       _amberDependentOneToOne = oneToOne;
237       
238       // oneToOne.setType(_targetBean.getEntityType());
239
//oneToOne.setCascadeDelete(_isCascadeDelete);
240

241       return oneToOne;
242     }
243     else {
244       EntityManyToOneField manyToOne;
245       manyToOne = new EntityManyToOneField(type, getName());
246       
247       _amberManyToOne = manyToOne;
248
249       manyToOne.setType(_targetBean.getEntityType());
250
251       manyToOne.setLinkColumns(calculateColumns(type, targetType));
252
253       manyToOne.setSourceCascadeDelete(_isSourceCascadeDelete);
254       manyToOne.setTargetCascadeDelete(_isTargetCascadeDelete);
255
256       return manyToOne;
257     }
258   }
259
260   private LinkColumns calculateColumns(EntityType type,
261                        EntityType targetType)
262     throws ConfigException
263   {
264     ArrayList JavaDoc<ForeignColumn> columns = new ArrayList JavaDoc<ForeignColumn>();
265
266     Id id = targetType.getId();
267     ArrayList JavaDoc<Column> keys = id.getColumns();
268
269     if (_sqlColumns != null && _sqlColumns.length == keys.size()) {
270       for (Column key : keys) {
271     String JavaDoc sqlColumn = getColumn(_sqlColumns, key.getName());
272     ForeignColumn column =
273       type.getTable().createForeignColumn(sqlColumn, key);
274     
275     columns.add(column);
276       }
277     }
278     else if (_sqlColumns != null && _sqlColumns.length == 1) {
279       String JavaDoc baseSqlColumn = _sqlColumns[0].getSQLColumn();
280       
281       for (Column key : keys) {
282     String JavaDoc sqlColumn = baseSqlColumn + "_" + key.getName();
283
284     ForeignColumn column =
285       type.getTable().createForeignColumn(sqlColumn, key);
286     columns.add(column);
287       }
288     }
289     else if (_sqlColumns != null && _sqlColumns.length > 0) {
290       throw new IllegalStateException JavaDoc("Mismatched SQL columns");
291     }
292     else if (keys.size() == 1) {
293       String JavaDoc sqlColumn = toSqlName(getName());
294       
295       ForeignColumn column =
296     type.getTable().createForeignColumn(sqlColumn, keys.get(0));
297       columns.add(column);
298     }
299     else {
300       String JavaDoc baseSqlColumn = toSqlName(getName());
301       for (Column key : keys) {
302     String JavaDoc sqlColumn = baseSqlColumn + "_" + key.getName();
303       
304     ForeignColumn column =
305       type.getTable().createForeignColumn(sqlColumn, key);
306     columns.add(column);
307       }
308     }
309
310     return new LinkColumns(type.getTable(), targetType.getTable(), columns);
311   }
312
313   private String JavaDoc getColumn(SqlRelation []sqlColumns, String JavaDoc sqlName)
314     throws ConfigException
315   {
316     String JavaDoc fieldName = getFieldName(_targetBean.getEntityType(), sqlName);
317     
318     if (sqlColumns.length == 1)
319       return sqlColumns[0].getSQLColumn();
320
321     for (int i = 0; i < sqlColumns.length; i++) {
322       String JavaDoc ref = sqlColumns[i].getReferences();
323
324       if (ref == null)
325     throw new ConfigException(L.l("sql-column '{0}' needs a references attribute.",
326                       sqlColumns[i].getSQLColumn()));
327
328       if (ref.equals(fieldName))
329     return sqlColumns[i].getSQLColumn();
330     }
331     
332     throw new ConfigException(L.l("key '{0}' has no matching sql-column",
333                   fieldName));
334   }
335
336   private String JavaDoc getFieldName(EntityType type, String JavaDoc sqlName)
337     throws ConfigException
338   {
339     for (IdField field : type.getId().getKeys()) {
340       ArrayList JavaDoc<Column> columns = field.getColumns();
341
342       for (int i = 0; i < columns.size(); i++)
343     if (columns.get(i).getName().equals(sqlName))
344       return field.getName();
345     }
346
347     return sqlName;
348   }
349   
350   /**
351    * Link amber.
352    */

353   public void linkAmber()
354     throws ConfigException
355   {
356     CmrRelation targetRelation = getTargetRelation();
357
358     if (targetRelation == null)
359       return;
360     else if (! (targetRelation instanceof CmrManyToOne))
361       return;
362     else if (_isDependent) {
363       CmrManyToOne targetManyToOne = (CmrManyToOne) targetRelation;
364
365       EntityManyToOneField amberTarget = targetManyToOne.getAmberManyToOne();
366
367       if (_amberDependentOneToOne == null) {
368     EntityType type = getEntity().getEntityType();
369     
370     DependentEntityOneToOneField oneToOne;
371     oneToOne = new DependentEntityOneToOneField(type, getName());
372
373     _amberDependentOneToOne = oneToOne;
374       }
375       
376       _amberDependentOneToOne.setTargetField(amberTarget);
377     }
378     else {
379       CmrManyToOne targetManyToOne = (CmrManyToOne) targetRelation;
380
381       DependentEntityOneToOneField amberTarget;
382       amberTarget = targetManyToOne.getAmberOneToOne();
383
384       EntityManyToOneField manyToOne = getAmberManyToOne();
385
386       if (amberTarget != null && manyToOne != null) {
387     manyToOne.setTargetField(amberTarget);
388     amberTarget.setTargetField(manyToOne);
389       }
390     }
391   }
392 }
393
Popular Tags