KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > cmp > jdbc2 > bridge > JDBCEntityBridge2


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb.plugins.cmp.jdbc2.bridge;
23
24 import org.jboss.deployment.DeploymentException;
25 import org.jboss.ejb.EntityContainer;
26 import org.jboss.ejb.EntityEnterpriseContext;
27 import org.jboss.ejb.plugins.cmp.bridge.EntityBridgeInvocationHandler;
28 import org.jboss.ejb.plugins.cmp.bridge.FieldBridge;
29 import org.jboss.ejb.plugins.cmp.jdbc.JDBCEntityPersistenceStore;
30 import org.jboss.ejb.plugins.cmp.jdbc.SQLUtil;
31 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractEntityBridge;
32 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge;
33 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractCMRFieldBridge;
34 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCCMPFieldMetaData;
35 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCEntityMetaData;
36 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationshipRoleMetaData;
37 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCOptimisticLockingMetaData;
38 import org.jboss.ejb.plugins.cmp.jdbc2.JDBCStoreManager2;
39 import org.jboss.ejb.plugins.cmp.jdbc2.PersistentContext;
40 import org.jboss.ejb.plugins.cmp.jdbc2.schema.EntityTable;
41 import org.jboss.logging.Logger;
42 import org.jboss.proxy.compiler.InvocationHandler;
43 import org.jboss.proxy.compiler.Proxies;
44
45 import javax.ejb.EJBException JavaDoc;
46 import javax.ejb.RemoveException JavaDoc;
47 import javax.sql.DataSource JavaDoc;
48 import java.util.ArrayList JavaDoc;
49 import java.util.Iterator JavaDoc;
50 import java.util.List JavaDoc;
51
52
53 /**
54  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
55  * @version <tt>$Revision: 37459 $</tt>
56  */

57 public class JDBCEntityBridge2
58    implements JDBCAbstractEntityBridge
59 {
60    private final JDBCStoreManager2 manager;
61    private final JDBCEntityMetaData metadata;
62    private final EntityTable table;
63    private final String JavaDoc tableName;
64    private final Logger log;
65
66    private JDBCCMPFieldBridge2[] pkFields;
67    private JDBCCMPFieldBridge2[] cmpFields;
68    private JDBCCMPFieldBridge2[] tableFields;
69    private JDBCCMRFieldBridge2[] cmrFields;
70    private JDBCCMPFieldBridge2 versionField;
71
72    private int cmrCount;
73
74    public JDBCEntityBridge2(JDBCStoreManager2 manager, JDBCEntityMetaData metadata) throws DeploymentException
75    {
76       this.manager = manager;
77       this.metadata = metadata;
78       log = Logger.getLogger(this.getClass().getName() + "." + metadata.getName());
79
80       table = manager.getSchema().createEntityTable(metadata, this);
81       tableName = SQLUtil.getTableNameWithoutSchema(metadata.getDefaultTableName());
82    }
83
84    // Public
85

86    public void init() throws DeploymentException
87    {
88       loadCMPFields(metadata);
89       loadCMRFields(metadata);
90
91       JDBCOptimisticLockingMetaData olMD = metadata.getOptimisticLocking();
92       if(olMD != null)
93       {
94          if(olMD.getLockingStrategy() != JDBCOptimisticLockingMetaData.VERSION_COLUMN_STRATEGY)
95          {
96             throw new DeploymentException(
97                "Only version-column optimistic locking strategy is supported at the moment.");
98          }
99
100          JDBCCMPFieldMetaData versionMD = olMD.getLockingField();
101          versionField = (JDBCCMPFieldBridge2) getFieldByName(versionMD.getFieldName());
102       }
103    }
104
105    public JDBCCMPFieldBridge2 getVersionField()
106    {
107       return versionField;
108    }
109
110    public void resolveRelationships() throws DeploymentException
111    {
112       for(int i = 0; i < cmrFields.length; ++i)
113       {
114          cmrFields[i].resolveRelationship();
115       }
116    }
117
118    public void start() throws DeploymentException
119    {
120       if(versionField != null)
121       {
122          versionField.initVersion();
123       }
124
125       table.start();
126
127       if(cmrFields != null)
128       {
129          for(int i = 0; i < cmrFields.length; ++i)
130          {
131             cmrFields[i].initLoader();
132          }
133       }
134    }
135
136    public void stop() throws Exception JavaDoc
137    {
138       table.stop();
139    }
140    
141    public JDBCEntityMetaData getMetaData()
142    {
143       return metadata;
144    }
145
146    public EntityTable getTable()
147    {
148       return table;
149    }
150
151    public JDBCFieldBridge[] getPrimaryKeyFields()
152    {
153       return pkFields;
154    }
155
156    public JDBCFieldBridge[] getTableFields()
157    {
158       return tableFields;
159    }
160
161    public JDBCAbstractCMRFieldBridge[] getCMRFields()
162    {
163       return cmrFields;
164    }
165
166    public JDBCEntityPersistenceStore getManager()
167    {
168       return manager;
169    }
170
171    public EntityContainer getContainer()
172    {
173       return manager.getContainer();
174    }
175
176    public Object JavaDoc extractPrimaryKeyFromInstance(EntityEnterpriseContext ctx)
177    {
178       try
179       {
180          Object JavaDoc pk = null;
181          for(int i = 0; i < pkFields.length; ++i)
182          {
183             JDBCCMPFieldBridge2 pkField = pkFields[i];
184             Object JavaDoc fieldValue = pkField.getValue(ctx);
185             pk = pkField.setPrimaryKeyValue(pk, fieldValue);
186          }
187          return pk;
188       }
189       catch(EJBException JavaDoc e)
190       {
191          throw e;
192       }
193       catch(Exception JavaDoc e)
194       {
195          throw new EJBException JavaDoc("Internal error extracting primary key from instance", e);
196       }
197    }
198
199    public static void destroyPersistenceContext(EntityEnterpriseContext ctx)
200    {
201       // If we have an EJB 2.0 dynaymic proxy,
202
// notify the handler of the assigned context.
203
Object JavaDoc instance = ctx.getInstance();
204       if(instance instanceof Proxies.ProxyTarget)
205       {
206          InvocationHandler handler = ((Proxies.ProxyTarget) instance).getInvocationHandler();
207          if(handler instanceof EntityBridgeInvocationHandler)
208          {
209             ((EntityBridgeInvocationHandler) handler).setContext(null);
210          }
211       }
212       ctx.setPersistenceContext(null);
213    }
214
215    public void initPersistenceContext(EntityEnterpriseContext ctx)
216    {
217       // If we have an EJB 2.0 dynaymic proxy,
218
// notify the handler of the assigned context.
219
Object JavaDoc instance = ctx.getInstance();
220       if(instance instanceof Proxies.ProxyTarget)
221       {
222          InvocationHandler handler = ((Proxies.ProxyTarget) instance).getInvocationHandler();
223          if(handler instanceof EntityBridgeInvocationHandler)
224          {
225             ((EntityBridgeInvocationHandler) handler).setContext(ctx);
226          }
227       }
228    }
229
230    public void initInstance(EntityEnterpriseContext ctx)
231    {
232       ctx.setPersistenceContext(new PersistentContext(this, table.getRow(ctx.getId())));
233       for(int i = 0; i < tableFields.length; ++i)
234       {
235          tableFields[i].initInstance(ctx);
236       }
237
238       for(int i = 0; i < cmrFields.length; ++i)
239       {
240          cmrFields[i].initInstance(ctx);
241       }
242    }
243
244    /**
245     * hacky method needed at deployment time
246     */

247    public List JavaDoc getFields()
248    {
249       List JavaDoc fields = new ArrayList JavaDoc();
250       for(int i = 0; i < pkFields.length; ++i)
251       {
252          fields.add(pkFields[i]);
253       }
254
255       for(int i = 0; i < cmpFields.length; ++i)
256       {
257          fields.add(cmpFields[i]);
258       }
259
260       for(int i = 0; i < cmrFields.length; ++i)
261       {
262          fields.add(cmrFields[i]);
263       }
264
265       return fields;
266    }
267
268    public boolean isStoreRequired(EntityEnterpriseContext instance)
269    {
270       PersistentContext pctx = (PersistentContext) instance.getPersistenceContext();
271       return pctx.isDirty();
272    }
273
274    public boolean isModified(EntityEnterpriseContext instance)
275    {
276       PersistentContext pctx = (PersistentContext) instance.getPersistenceContext();
277       boolean modified = pctx.isDirty();
278
279       if(!modified && cmrFields != null)
280       {
281          for(int i = 0; i < cmrFields.length; ++i)
282          {
283             final JDBCCMRFieldBridge2.FieldState cmrState = pctx.getCMRState(i);
284             if(cmrState != null && cmrState.isModified())
285             {
286                modified = true;
287                break;
288             }
289          }
290       }
291       return modified;
292    }
293    
294    public Class JavaDoc getPrimaryKeyClass()
295    {
296       return metadata.getPrimaryKeyClass();
297    }
298
299    public Class JavaDoc getHomeClass()
300    {
301       return metadata.getHomeClass();
302    }
303
304    public Class JavaDoc getLocalHomeClass()
305    {
306       return metadata.getLocalHomeClass();
307    }
308
309    public String JavaDoc getTableName()
310    {
311       return tableName;
312    }
313
314    public String JavaDoc getQualifiedTableName()
315    {
316       return metadata.getDefaultTableName();
317    }
318
319    public DataSource JavaDoc getDataSource()
320    {
321       return table.getDataSource();
322    }
323
324    public boolean[] getLoadGroupMask(String JavaDoc eagerLoadGroupName)
325    {
326       // todo
327
throw new UnsupportedOperationException JavaDoc();
328    }
329
330    public int getNextCMRIndex()
331    {
332       return cmrCount++;
333    }
334
335    public void remove(EntityEnterpriseContext ctx) throws RemoveException JavaDoc
336    {
337       if(cmrFields != null)
338       {
339          for(int i = 0; i < cmrFields.length; ++i)
340          {
341             cmrFields[i].remove(ctx);
342          }
343       }
344    }
345
346    // EntityBridge implementation
347

348    public String JavaDoc getEntityName()
349    {
350       return metadata.getName();
351    }
352
353    public String JavaDoc getAbstractSchemaName()
354    {
355       return metadata.getAbstractSchemaName();
356    }
357
358    public FieldBridge getFieldByName(String JavaDoc fieldName)
359    {
360       FieldBridge field;
361       for(int i = 0; i < pkFields.length; ++i)
362       {
363          field = pkFields[i];
364          if(field.getFieldName().equals(fieldName))
365          {
366             return field;
367          }
368       }
369
370       for(int i = 0; i < cmpFields.length; ++i)
371       {
372          field = cmpFields[i];
373          if(field.getFieldName().equals(fieldName))
374          {
375             return field;
376          }
377       }
378
379       for(int i = 0; i < cmrFields.length; ++i)
380       {
381          field = cmrFields[i];
382          if(field.getFieldName().equals(fieldName))
383          {
384             return field;
385          }
386       }
387
388       throw new IllegalStateException JavaDoc("Field " + fieldName + " not found in entity " + getEntityName());
389    }
390
391    public Class JavaDoc getRemoteInterface()
392    {
393       return metadata.getRemoteClass();
394    }
395
396    public Class JavaDoc getLocalInterface()
397    {
398       return metadata.getLocalClass();
399    }
400
401    // Package
402

403    JDBCCMPFieldBridge2 addTableField(JDBCCMPFieldMetaData metadata) throws DeploymentException
404    {
405       table.addField();
406       if(tableFields == null)
407       {
408          tableFields = new JDBCCMPFieldBridge2[1];
409       }
410       else
411       {
412          JDBCCMPFieldBridge2[] tmp = tableFields;
413          tableFields = new JDBCCMPFieldBridge2[tableFields.length + 1];
414          System.arraycopy(tmp, 0, tableFields, 0, tmp.length);
415       }
416       int tableIndex = tableFields.length - 1;
417       JDBCCMPFieldBridge2 cmpField = new JDBCCMPFieldBridge2(manager, this, metadata, tableIndex);
418       tableFields[tableFields.length - 1] = cmpField;
419       return cmpField;
420    }
421
422    // Private
423

424    private void loadCMPFields(JDBCEntityMetaData metadata) throws DeploymentException
425    {
426       // only non pk fields are stored here at first and then later
427
// the pk fields are added to the front (makes sql easier to read)
428
List JavaDoc cmpFieldsList = new ArrayList JavaDoc(metadata.getCMPFields().size());
429       // primary key cmp fields
430
List JavaDoc pkFieldsList = new ArrayList JavaDoc(metadata.getCMPFields().size());
431
432       // create each field
433
Iterator JavaDoc iter = metadata.getCMPFields().iterator();
434       while(iter.hasNext())
435       {
436          JDBCCMPFieldMetaData cmpFieldMetaData = (JDBCCMPFieldMetaData) iter.next();
437          JDBCCMPFieldBridge2 cmpField = addTableField(cmpFieldMetaData);
438          if(cmpFieldMetaData.isPrimaryKeyMember())
439          {
440             pkFieldsList.add(cmpField);
441          }
442          else
443          {
444             cmpFieldsList.add(cmpField);
445          }
446       }
447
448       // save the pk fields in the pk field array
449
pkFields = new JDBCCMPFieldBridge2[pkFieldsList.size()];
450       for(int i = 0; i < pkFieldsList.size(); ++i)
451       {
452          pkFields[i] = (JDBCCMPFieldBridge2) pkFieldsList.get(i);
453       }
454
455       // add the pk fields to the front of the cmp list, per guarantee above
456
cmpFields = new JDBCCMPFieldBridge2[metadata.getCMPFields().size() - pkFields.length];
457       int cmpFieldIndex = 0;
458       for(int i = 0; i < cmpFieldsList.size(); ++i)
459       {
460          cmpFields[cmpFieldIndex++] = (JDBCCMPFieldBridge2) cmpFieldsList.get(i);
461       }
462    }
463
464    private void loadCMRFields(JDBCEntityMetaData metadata)
465       throws DeploymentException
466    {
467       cmrFields = new JDBCCMRFieldBridge2[metadata.getRelationshipRoles().size()];
468       // create each field
469
int cmrFieldIndex = 0;
470       for(Iterator JavaDoc iter = metadata.getRelationshipRoles().iterator(); iter.hasNext();)
471       {
472          JDBCRelationshipRoleMetaData relationshipRole = (JDBCRelationshipRoleMetaData) iter.next();
473          JDBCCMRFieldBridge2 cmrField = new JDBCCMRFieldBridge2(this, manager, relationshipRole);
474          cmrFields[cmrFieldIndex++] = cmrField;
475       }
476    }
477 }
478
Popular Tags