KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > amber > entity > AmberEntityHome


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  * Free Software Foundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.amber.entity;
30
31 import com.caucho.amber.AmberException;
32 import com.caucho.amber.manager.AmberConnection;
33 import com.caucho.amber.manager.AmberPersistenceUnit;
34 import com.caucho.amber.query.CacheUpdate;
35 import com.caucho.amber.type.EntityType;
36 import com.caucho.config.ConfigException;
37 import com.caucho.log.Log;
38 import com.caucho.util.L10N;
39
40 import java.lang.ref.SoftReference JavaDoc;
41 import java.lang.reflect.Method JavaDoc;
42 import java.sql.ResultSet JavaDoc;
43 import java.sql.SQLException JavaDoc;
44 import java.util.ArrayList JavaDoc;
45 import java.util.Map JavaDoc;
46 import java.util.logging.Level JavaDoc;
47 import java.util.logging.Logger JavaDoc;
48
49 /**
50  * Manages the set of persistent beans.
51  */

52 public class AmberEntityHome {
53   private static final L10N L = new L10N(AmberEntityHome.class);
54   private static final Logger JavaDoc log = Log.open(AmberEntityHome.class);
55
56   private AmberPersistenceUnit _manager;
57   private EntityType _entityType;
58
59   private EntityFactory _entityFactory = new EntityFactory();
60
61   private Entity _homeBean;
62
63   private ArrayList JavaDoc<SoftReference JavaDoc<CacheUpdate>> _cacheUpdates =
64     new ArrayList JavaDoc<SoftReference JavaDoc<CacheUpdate>>();
65
66   private EntityKey _cacheKey = new EntityKey();
67
68   private volatile boolean _isInit;
69
70   private ConfigException _configException;
71
72   private Method JavaDoc _cauchoGetBeanMethod;
73
74   public AmberEntityHome(AmberPersistenceUnit manager, EntityType type)
75   {
76     _manager = manager;
77     _entityType = type;
78
79     try {
80       Class JavaDoc cl = Class.forName("com.caucho.ejb.entity.EntityObject");
81       _cauchoGetBeanMethod = cl.getMethod("_caucho_getBean", new Class JavaDoc[0]);
82     } catch (Throwable JavaDoc e) {
83       log.log(Level.FINEST, e.toString(), e);
84     }
85   }
86
87   /**
88    * Returns the manager.
89    */

90   public AmberPersistenceUnit getManager()
91   {
92     return _manager;
93   }
94
95   /**
96    * Returns the entity type
97    */

98   public EntityType getEntityType()
99   {
100     return _entityType;
101   }
102
103   /**
104    * Returns the entity type
105    */

106   public EntityType getRootType()
107   {
108     return (EntityType) _entityType.getRootType();
109   }
110
111   /**
112    * Returns the entity factory.
113    */

114   public EntityFactory getEntityFactory()
115   {
116     return _entityFactory;
117   }
118
119   /**
120    * Sets the entity factory.
121    */

122   public void setEntityFactory(EntityFactory factory)
123   {
124     _entityFactory = factory;
125   }
126
127   /**
128    * Returns the cache timeout.
129    */

130   public long getCacheTimeout()
131   {
132     return _entityType.getCacheTimeout();
133   }
134
135   /**
136    * Returns the instance class.
137    */

138   public Class JavaDoc getInstanceClass()
139   {
140     return _entityType.getInstanceClass();
141   }
142
143   /**
144    * Link the classes.
145    */

146   void link()
147     throws ConfigException
148   {
149     // _entityClass.link(_manager);
150
}
151
152   /**
153    * Initialize the home.
154    */

155   public void init()
156     throws ConfigException
157   {
158     synchronized (this) {
159       if (_isInit)
160         return;
161       _isInit = true;
162     }
163
164     _entityType.init();
165
166     try {
167       _homeBean = (Entity) _entityType.getInstanceClass().newInstance();
168     } catch (Exception JavaDoc e) {
169       _entityType.setConfigException(e);
170
171       _configException = new ConfigException(e);
172       throw _configException;
173     }
174
175     _entityType.start();
176   }
177
178   /**
179    * Returns the entity from the key.
180    */

181   public Object JavaDoc getKeyFromEntity(Entity entity)
182     throws AmberException
183   {
184     // return _entityType.getId().getType().getValue(obj);
185
return null;
186   }
187
188   /**
189    * Converts a long key to the key.
190    */

191   public Object JavaDoc toObjectKey(long key)
192   {
193     return _entityType.getId().toObjectKey(key);
194   }
195
196   /**
197    * Finds by the primary key.
198    */

199   public Entity load(AmberConnection aConn,
200                      Object JavaDoc key)
201     throws AmberException
202   {
203     return load(aConn, key, null);
204   }
205
206   /**
207    * Finds by the primary key.
208    */

209   public Entity load(AmberConnection aConn,
210                      Object JavaDoc key,
211                      Map JavaDoc preloadedProperties)
212     throws AmberException
213   {
214     return find(aConn, key, true, preloadedProperties);
215   }
216
217   /**
218    * Finds by the primary key.
219    */

220   public Entity loadLazy(AmberConnection aConn, Object JavaDoc key)
221     throws AmberException
222   {
223     return find(aConn, key, false);
224   }
225
226   /**
227    * Finds by the primary key.
228    */

229   public EntityItem findItem(AmberConnection aConn,
230                              ResultSet JavaDoc rs, int index)
231     throws SQLException JavaDoc
232   {
233     return _homeBean.__caucho_home_find(aConn, this, rs, index);
234   }
235
236   /**
237    * Finds by the primary key.
238    */

239   public Object JavaDoc loadFull(AmberConnection aConn, ResultSet JavaDoc rs, int index)
240     throws SQLException JavaDoc
241   {
242     EntityItem item = findItem(aConn, rs, index);
243
244     if (item == null)
245       return null;
246
247     Entity entity = null;
248
249     Object JavaDoc value = _entityFactory.getEntity(aConn, item);
250
251     if (aConn.isInTransaction()) {
252       if (value instanceof Entity)
253         entity = (Entity) value;
254       else if (_cauchoGetBeanMethod != null) {
255         try {
256           entity = (Entity) _cauchoGetBeanMethod.invoke(value, new Object JavaDoc[0]);
257           entity.__caucho_makePersistent(aConn, item);
258         } catch (Throwable JavaDoc e) {
259           log.log(Level.FINEST, e.toString(), e);
260         }
261       }
262
263       if (entity == null)
264         entity = aConn.getEntity(item);
265     }
266     else
267       entity = item.getEntity();
268
269     int keyLength = _entityType.getId().getKeyCount();
270
271     entity.__caucho_load(aConn, rs, index + keyLength);
272
273     return value;
274   }
275
276   /**
277    * Finds by the primary key.
278    */

279   public Object JavaDoc loadLazy(AmberConnection aConn, ResultSet JavaDoc rs, int index)
280     throws SQLException JavaDoc
281   {
282     EntityItem item = findItem(aConn, rs, index);
283
284     if (item == null)
285       return null;
286
287     return _entityFactory.getEntity(aConn, item);
288   }
289
290   /**
291    * Finds an entity based on the primary key.
292    *
293    * @param key the primary key
294    * @param aConn the Amber connection to associate with the loaded item
295    * @param isLoad if true, try to load the bean
296    */

297   public Entity find(AmberConnection aConn,
298                      Object JavaDoc key,
299                      boolean isLoad)
300     throws AmberException
301   {
302     return find(aConn, key, isLoad, null);
303   }
304
305   /**
306    * Finds an entity based on the primary key.
307    *
308    * @param key the primary key
309    * @param aConn the Amber connection to associate with the loaded item
310    * @param isLoad if true, try to load the bean
311    */

312   public Entity find(AmberConnection aConn,
313                      Object JavaDoc key,
314                      boolean isLoad,
315                      Map JavaDoc preloadedProperties)
316     throws AmberException
317   {
318     EntityItem item = findEntityItem(aConn, key, isLoad, preloadedProperties);
319
320     if (item == null)
321       return null;
322
323     // throw new AmberObjectNotFoundException(("amber find: no matching object " + _entityType.getBeanClass().getName() + "[" + key + "]"));
324

325     return item.copy(aConn);
326   }
327
328   /**
329    * Loads an entity based on the primary key.
330    *
331    * @param aConn the Amber connection to associate with the loaded item
332    * @param key the primary key
333    * @param isLoad if true, try to load the bean
334    */

335   public EntityItem findEntityItem(AmberConnection aConn,
336                                    Object JavaDoc key,
337                                    boolean isLoad)
338     throws AmberException
339   {
340     return findEntityItem(aConn, key, isLoad, null);
341   }
342
343   /**
344    * Loads an entity based on the primary key.
345    *
346    * @param aConn the Amber connection to associate with the loaded item
347    * @param key the primary key
348    * @param isLoad if true, try to load the bean
349    */

350   public EntityItem findEntityItem(AmberConnection aConn,
351                                    Object JavaDoc key,
352                                    boolean isLoad,
353                                    Map JavaDoc preloadedProperties)
354     throws AmberException
355   {
356     if (key == null)
357       return null; // ejb/0a06 throw new NullPointerException("primaryKey");
358

359     try {
360       EntityItem item = null;
361
362       // XXX: ejb/0d01 should not check this.
363
// jpa/0y14 if (aConn.shouldRetrieveFromCache())
364
item = _manager.getEntity(getRootType(), key);
365
366       if (item == null) {
367         if (_homeBean == null && _configException != null)
368           throw _configException;
369
370         // XXX: this is an initial optimization and bug fix also for jpa/0s29
371
// XXX: another point is inheritance with many-to-one (jpa/0l40 and jpa/0s29)
372
// still get twice the number of loading SQLs.
373
boolean loadFromResultSet = ! getEntityType().hasDependent();
374
375         Entity cacheEntity;
376         cacheEntity = (Entity) _homeBean.__caucho_home_new(aConn, this, key, loadFromResultSet);
377
378         // Object does not exist.
379
if (cacheEntity == null)
380           return null;
381
382         if (isLoad) {
383           cacheEntity.__caucho_retrieve(aConn, preloadedProperties);
384         }
385
386         item = new CacheableEntityItem(this, cacheEntity);
387         item = _manager.putEntity(getRootType(), key, item);
388       }
389       else if (isLoad) {
390         item.loadEntity(0, preloadedProperties);
391       }
392
393       return item;
394     } catch (Exception JavaDoc e) {
395       throw AmberException.create(e);
396     }
397   }
398
399   /**
400    * Loads an entity based on the primary key.
401    *
402    * @param key the primary key
403    * @param aConn the Amber connection to associate with the loaded item
404    * @param isLoad if true, try to load the bean
405    */

406   public EntityItem setEntityItem(Object JavaDoc key, EntityItem item)
407     throws AmberException
408   {
409     if (key == null)
410       throw new NullPointerException JavaDoc("primaryKey");
411
412     try {
413       item.getEntity().__caucho_setConnection(_manager.getCacheConnection());
414
415       return _manager.putEntity(getRootType(), key, item);
416     } catch (Exception JavaDoc e) {
417       throw AmberException.create(e);
418     }
419   }
420
421   /**
422    * Loads an entity where the type is determined by a discriminator
423    *
424    * @param aConn the connection to associate with the entity
425    * @param key the primary key
426    * @param discriminator the object's discriminator
427    */

428   public EntityItem findDiscriminatorEntityItem(AmberConnection aConn,
429                                                 Object JavaDoc key,
430                                                 String JavaDoc discriminator)
431     throws SQLException JavaDoc
432   {
433     EntityItem item = null;
434
435     // XXX: ejb/0d01
436
if (aConn.shouldRetrieveFromCache())
437       item = _manager.getEntity(getRootType(), key);
438
439     if (item == null) {
440       EntityType subEntity
441         = (EntityType) _entityType.getSubClass(discriminator);
442
443       Entity cacheEntity = subEntity.createBean();
444
445       cacheEntity.__caucho_setPrimaryKey(key);
446       cacheEntity.__caucho_makePersistent(_manager.getCacheConnection(),
447                                           subEntity);
448
449       item = new CacheableEntityItem(this, cacheEntity);
450       item = _manager.putEntity(getRootType(), key, item);
451     }
452
453     return item;
454   }
455
456   /**
457    * Finds by the primary key.
458    */

459   public Entity makePersistent(Entity entity,
460                                AmberConnection aConn,
461                                boolean isLazy)
462     throws SQLException JavaDoc
463   {
464     entity.__caucho_makePersistent(aConn, _entityType);
465
466     return entity;
467   }
468
469   /**
470    * Saves based on the object.
471    */

472   public void save(AmberConnection aConn, Entity entity)
473     throws SQLException JavaDoc
474   {
475     entity.__caucho_create(aConn, _entityType);
476   }
477
478   /**
479    * Deletes by the primary key.
480    */

481   public void delete(AmberConnection aConn, Object JavaDoc key)
482     throws SQLException JavaDoc
483   {
484     _manager.removeEntity(getRootType(), key);
485
486     /*
487       _entityType.childDelete(aConn, key);
488
489       // XXX: possibly move somewhere else?
490       synchronized (_cacheUpdates) {
491       for (int i = _cacheUpdates.size() - 1; i >= 0; i--) {
492       SoftReference<CacheUpdate> ref = _cacheUpdates.get(i);
493       CacheUpdate update = ref.get();
494
495       if (update == null)
496       _cacheUpdates.remove(i);
497       else
498       update.delete(primaryKey);
499       }
500       }
501     */

502   }
503
504   /**
505    * Deletes by the primary key.
506    */

507   public void delete(AmberConnection aConn, long primaryKey)
508     throws SQLException JavaDoc
509   {
510     /*
511       _entityClass.childDelete(session, primaryKey);
512
513       // XXX: possibly move somewhere else?
514       synchronized (_cacheUpdates) {
515       for (int i = _cacheUpdates.size() - 1; i >= 0; i--) {
516       SoftReference<CacheUpdate> ref = _cacheUpdates.get(i);
517       CacheUpdate update = ref.get();
518
519       if (update == null)
520       _cacheUpdates.remove(i);
521       else
522       update.delete(primaryKey);
523       }
524       }
525     */

526   }
527
528   /**
529    * Update for a modification.
530    */

531   public void update(Entity entity)
532     throws SQLException JavaDoc
533   {
534   }
535
536   /**
537    * Adds a cache update.
538    */

539   public void addUpdate(CacheUpdate update)
540   {
541     _cacheUpdates.add(new SoftReference JavaDoc<CacheUpdate>(update));
542   }
543 }
544
Popular Tags