KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > amber > manager > AmberPersistenceUnit


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.amber.manager;
31
32 import com.caucho.amber.AmberException;
33 import com.caucho.amber.AmberRuntimeException;
34 import com.caucho.amber.cfg.BaseConfigIntrospector;
35 import com.caucho.amber.cfg.EmbeddableIntrospector;
36 import com.caucho.amber.cfg.EntityIntrospector;
37 import com.caucho.amber.cfg.EntityMappingsConfig;
38 import com.caucho.amber.cfg.MappedSuperIntrospector;
39 import com.caucho.amber.cfg.NamedNativeQueryConfig;
40 import com.caucho.amber.cfg.SqlResultSetMappingConfig;
41 import com.caucho.amber.entity.AmberCompletion;
42 import com.caucho.amber.entity.AmberEntityHome;
43 import com.caucho.amber.entity.Entity;
44 import com.caucho.amber.entity.EntityItem;
45 import com.caucho.amber.entity.EntityKey;
46 import com.caucho.amber.entity.Listener;
47 import com.caucho.amber.gen.AmberGenerator;
48 import com.caucho.amber.gen.AmberGeneratorImpl;
49 import com.caucho.amber.idgen.IdGenerator;
50 import com.caucho.amber.idgen.SequenceIdGenerator;
51 import com.caucho.amber.query.QueryCacheKey;
52 import com.caucho.amber.query.ResultSetCacheChunk;
53 import com.caucho.amber.table.Table;
54 import com.caucho.amber.type.*;
55 import com.caucho.bytecode.JClass;
56 import com.caucho.bytecode.JClassLoader;
57 import com.caucho.bytecode.JMethod;
58 import com.caucho.config.ConfigException;
59 import com.caucho.java.gen.JavaClassGenerator;
60 import com.caucho.jdbc.JdbcMetaData;
61 import com.caucho.naming.Jndi;
62 import com.caucho.util.L10N;
63 import com.caucho.util.LruCache;
64
65 import javax.persistence.EntityManager;
66 import javax.sql.DataSource JavaDoc;
67 import java.io.IOException JavaDoc;
68 import java.lang.ref.SoftReference JavaDoc;
69 import java.sql.ResultSetMetaData JavaDoc;
70 import java.util.ArrayList JavaDoc;
71 import java.util.HashMap JavaDoc;
72 import java.util.Iterator JavaDoc;
73 import java.util.logging.Level JavaDoc;
74 import java.util.logging.Logger JavaDoc;
75
76 /**
77  * Main interface between Resin and the connector. It's the
78  * top-level SPI class for creating the SPI ManagedConnections.
79  *
80  * The resource configuration in Resin's web.xml will use bean-style
81  * configuration to configure the ManagecConnectionFactory.
82  */

83 public class AmberPersistenceUnit {
84   private static final L10N L = new L10N(AmberPersistenceUnit.class);
85   private static final Logger JavaDoc log
86     = Logger.getLogger(AmberPersistenceUnit.class.getName());
87
88   private String JavaDoc _name;
89
90   private boolean _isJPA;
91
92   private AmberContainer _amberContainer;
93
94   // Actual class is EntityManagerProxy, but EntityManager is JDK 1.5 dependent
95
private Object JavaDoc _entityManagerProxy;
96
97   // basic data source
98
private DataSource JavaDoc _dataSource;
99
100   // data source for read-only requests
101
private DataSource JavaDoc _readDataSource;
102
103   // data source for requests in a transaction
104
private DataSource JavaDoc _xaDataSource;
105
106   private JdbcMetaData _jdbcMetaData;
107
108   private boolean _createDatabaseTables;
109   private boolean _validateDatabaseTables = true;
110
111   // private long _tableCacheTimeout = 250;
112
private long _tableCacheTimeout = 2000;
113
114   private TypeManager _typeManager = new TypeManager();
115
116   private HashMap JavaDoc<String JavaDoc,Table> _tableMap =
117     new HashMap JavaDoc<String JavaDoc,Table>();
118
119   private HashMap JavaDoc<String JavaDoc,AmberEntityHome> _entityHomeMap =
120     new HashMap JavaDoc<String JavaDoc,AmberEntityHome>();
121
122   private HashMap JavaDoc<String JavaDoc,IdGenerator> _tableGenMap =
123     new HashMap JavaDoc<String JavaDoc,IdGenerator>();
124
125   private HashMap JavaDoc<String JavaDoc,SequenceIdGenerator> _sequenceGenMap =
126     new HashMap JavaDoc<String JavaDoc,SequenceIdGenerator>();
127
128   private LruCache<QueryCacheKey,SoftReference JavaDoc<ResultSetCacheChunk>> _queryCache =
129     new LruCache<QueryCacheKey,SoftReference JavaDoc<ResultSetCacheChunk>>(1024);
130
131   private LruCache<QueryCacheKey,SoftReference JavaDoc<ResultSetMetaData JavaDoc>> _queryCacheMetaData =
132     new LruCache<QueryCacheKey,SoftReference JavaDoc<ResultSetMetaData JavaDoc>>(16);
133
134   private LruCache<EntityKey,SoftReference JavaDoc<EntityItem>> _entityCache =
135     new LruCache<EntityKey,SoftReference JavaDoc<EntityItem>>(32 * 1024);
136
137   private EntityKey _entityKey = new EntityKey();
138
139   private ArrayList JavaDoc<EntityType> _lazyConfigure = new ArrayList JavaDoc<EntityType>();
140
141   private ArrayList JavaDoc<EntityType> _lazyGenerate = new ArrayList JavaDoc<EntityType>();
142   private ArrayList JavaDoc<AmberEntityHome> _lazyHomeInit =
143     new ArrayList JavaDoc<AmberEntityHome>();
144   private ArrayList JavaDoc<Table> _lazyTable = new ArrayList JavaDoc<Table>();
145
146   private HashMap JavaDoc<String JavaDoc,String JavaDoc> _namedQueryMap =
147     new HashMap JavaDoc<String JavaDoc,String JavaDoc>();
148
149   private HashMap JavaDoc<String JavaDoc, SqlResultSetMappingConfig> _sqlResultSetMap =
150     new HashMap JavaDoc<String JavaDoc, SqlResultSetMappingConfig>();
151
152   private HashMap JavaDoc<String JavaDoc, NamedNativeQueryConfig> _namedNativeQueryMap =
153     new HashMap JavaDoc<String JavaDoc, NamedNativeQueryConfig>();
154
155   private EntityMappingsConfig _entityMappings;
156
157   private ArrayList JavaDoc<EmbeddableType> _embeddableTypes
158     = new ArrayList JavaDoc<EmbeddableType>();
159
160   private ArrayList JavaDoc<ListenerType> _defaultListeners =
161     new ArrayList JavaDoc<ListenerType>();
162
163   private EntityIntrospector _entityIntrospector;
164   private EmbeddableIntrospector _embeddableIntrospector;
165   private MappedSuperIntrospector _mappedSuperIntrospector;
166
167   private AmberGenerator _generator;
168
169   // private boolean _supportsGetGeneratedKeys;
170

171   private ThreadLocal JavaDoc<AmberConnection> _threadConnection
172     = new ThreadLocal JavaDoc<AmberConnection>();
173
174   private volatile boolean _isInit;
175
176   private long _xid = 1;
177
178   public AmberPersistenceUnit(AmberContainer container,
179                               String JavaDoc name)
180   {
181     _amberContainer = container;
182     _name = name;
183
184     _dataSource = container.getDataSource();
185     _xaDataSource = container.getXADataSource();
186     _readDataSource = container.getReadDataSource();
187
188     _createDatabaseTables = container.getCreateDatabaseTables();
189
190     _embeddableIntrospector = new EmbeddableIntrospector(this);
191     _entityIntrospector = new EntityIntrospector(this);
192     _mappedSuperIntrospector = new MappedSuperIntrospector(this);
193
194     // needed to support JDK 1.4 compatibility
195
try {
196       bindProxy();
197     } catch (Throwable JavaDoc e) {
198       log.log(Level.FINE, e.toString(), e);
199     }
200   }
201
202   public void setName(String JavaDoc name)
203   {
204     _name = name;
205   }
206
207   public String JavaDoc getName()
208   {
209     return _name;
210   }
211
212   private void bindProxy()
213     throws Exception JavaDoc
214   {
215     Jndi.bindDeep(_amberContainer.getPersistenceUnitJndiPrefix() + getName(),
216                   new FactoryProxy(this));
217
218     Jndi.bindDeep(_amberContainer.getPersistenceContextJndiPrefix() + getName(),
219                   new EntityManagerNamingProxy(this));
220   }
221
222   public EntityManager getEntityManager()
223   {
224     // return (EntityManager) _entityManagerProxy;
225

226     return null;
227   }
228
229   public AmberContainer getAmberContainer()
230   {
231     return _amberContainer;
232   }
233
234   public ClassLoader JavaDoc getEnhancedLoader()
235   {
236     return _amberContainer.getEnhancedLoader();
237   }
238
239   /**
240    * Sets the data source.
241    */

242   public void setDataSource(DataSource JavaDoc dataSource)
243   {
244     _dataSource = dataSource;
245   }
246
247   /**
248    * Gets the data source.
249    */

250   public DataSource JavaDoc getDataSource()
251   {
252     return _dataSource;
253   }
254
255   /**
256    * Sets the read data source.
257    */

258   public void setReadDataSource(DataSource JavaDoc dataSource)
259   {
260     _readDataSource = dataSource;
261   }
262
263   /**
264    * Gets the read data source.
265    */

266   public DataSource JavaDoc getReadDataSource()
267   {
268     return _readDataSource;
269   }
270
271   /**
272    * Sets the XA data source.
273    */

274   public void setXADataSource(DataSource JavaDoc dataSource)
275   {
276     _xaDataSource = dataSource;
277   }
278
279   /**
280    * Gets the xa data source.
281    */

282   public DataSource JavaDoc getXADataSource()
283   {
284     return _xaDataSource;
285   }
286
287   /**
288    * Returns the jdbc meta data.
289    */

290   public JdbcMetaData getMetaData()
291   {
292     if (_jdbcMetaData == null) {
293       if (getDataSource() == null)
294         throw new NullPointerException JavaDoc("No data-source specified for PersistenceUnit");
295
296       _jdbcMetaData = JdbcMetaData.create(getDataSource());
297     }
298
299     return _jdbcMetaData;
300   }
301
302   /**
303    * Set true if database tables should be created automatically.
304    */

305   public void setCreateDatabaseTables(boolean create)
306   {
307     _createDatabaseTables = create;
308   }
309
310   /**
311    * Set true if database tables should be created automatically.
312    */

313   public boolean getCreateDatabaseTables()
314   {
315     return _createDatabaseTables;
316   }
317
318   /**
319    * Set true if database tables should be validated automatically.
320    */

321   public void setValidateDatabaseTables(boolean validate)
322   {
323     _validateDatabaseTables = validate;
324   }
325
326   /**
327    * Set true if database tables should be validated automatically.
328    */

329   public boolean getValidateDatabaseTables()
330   {
331     return _validateDatabaseTables;
332   }
333
334   /**
335    * Set the default table cache time.
336    */

337   public void setTableCacheTimeout(long timeout)
338   {
339     _tableCacheTimeout = timeout;
340   }
341
342   /**
343    * Get the default table cache time.
344    */

345   public long getTableCacheTimeout()
346   {
347     return _tableCacheTimeout;
348   }
349
350   /**
351    * Set false for EJB-style generation.
352    */

353   public void setBytecodeGenerator(boolean isBytecodeGenerator)
354   {
355     if (isBytecodeGenerator)
356       _generator = _amberContainer.getGenerator();
357     else
358       _generator = new AmberGeneratorImpl(this);
359   }
360
361   /**
362    * Returns a new xid.
363    */

364   public long getXid()
365   {
366     synchronized (this) {
367       return _xid++;
368     }
369   }
370
371   /**
372    * Returns the enhanced loader.
373    */

374   public JClassLoader getJClassLoader()
375   {
376     return _amberContainer.getJClassLoader();
377   }
378
379   /**
380    * Creates a table.
381    */

382   public Table createTable(String JavaDoc tableName)
383   {
384     Table table = _tableMap.get(tableName);
385
386     if (table == null) {
387       table = new Table(this, tableName);
388       table.setCacheTimeout(getTableCacheTimeout());
389
390       _tableMap.put(tableName, table);
391
392       _lazyTable.add(table);
393     }
394
395     return table;
396   }
397
398   public Throwable JavaDoc getConfigException()
399   {
400     return _amberContainer.getConfigException();
401   }
402
403   /**
404    * Add an entity.
405    *
406    * @param className the class name
407    * @param type the JClass type if it is already verified as an
408    * Entity | Embeddable | MappedSuperclass
409    */

410   public void addEntityClass(String JavaDoc className,
411                              JClass type)
412     throws ConfigException
413   {
414     if (type == null) {
415       type = getJClassLoader().forName(className);
416
417       if (type == null) {
418         throw new ConfigException(L.l("'{0}' is an unknown type",
419                                       className));
420       }
421     }
422
423     boolean isEntity = _entityIntrospector.isEntity(type);
424     boolean isEmbeddable = _embeddableIntrospector.isEmbeddable(type);
425     boolean isMappedSuper = _mappedSuperIntrospector.isMappedSuper(type);
426
427     if (! (isEntity || isEmbeddable || isMappedSuper)) {
428       throw new ConfigException(L.l("'{0}' must implement javax.persistence.Entity, javax.persistence.Embeddable or javax.persistence.MappedSuperclass",
429                                     className));
430     }
431
432     try {
433       if (isEntity) {
434         EntityType entityType = _entityIntrospector.introspect(type);
435
436         // EntityType entity = createEntity(type);
437

438         _amberContainer.addEntity(className, entityType);
439       }
440       else if (isEmbeddable) {
441         EmbeddableType embeddableType = _embeddableIntrospector.introspect(type);
442
443         _amberContainer.addEmbeddable(className, embeddableType);
444       }
445       else if (isMappedSuper) {
446         // XXX: to do
447
// MappedSuperType mappedType = _mappedSuperIntrospector.introspect(type);
448
// _amberContainer.addMappedSuper(className, mappedType);
449
}
450     } catch (Throwable JavaDoc e) {
451       _amberContainer.addEntityException(className, e);
452
453       throw new ConfigException(e);
454     }
455   }
456
457   /**
458    * Adds a sql result set mapping.
459    */

460   public void addSqlResultSetMapping(String JavaDoc resultSetName,
461                                      SqlResultSetMappingConfig resultSet)
462     throws ConfigException
463   {
464     if (_sqlResultSetMap.containsKey(resultSetName)) {
465       throw new ConfigException(L.l("SqlResultSetMapping '{0}' is already defined.",
466                                     resultSetName));
467     }
468
469     _sqlResultSetMap.put(resultSetName, resultSet);
470   }
471
472   /**
473    * Returns the sql result set mapping.
474    */

475   public SqlResultSetMappingConfig getSqlResultSetMapping(String JavaDoc resultSetName)
476   {
477     return _sqlResultSetMap.get(resultSetName);
478   }
479
480   /**
481    * Adds a named query.
482    */

483   public void addNamedQuery(String JavaDoc name,
484                             String JavaDoc query)
485     throws ConfigException
486   {
487     if (_namedQueryMap.containsKey(name)) {
488       throw new ConfigException(L.l("Named query '{0}': '{1}' is already defined.",
489                                     name, query));
490     }
491
492     _namedQueryMap.put(name, query);
493   }
494
495   /**
496    * Returns the named query statement.
497    */

498   public String JavaDoc getNamedQuery(String JavaDoc name)
499   {
500     return (String JavaDoc) _namedQueryMap.get(name);
501   }
502
503   /**
504    * Adds a named native query.
505    */

506   public void addNamedNativeQuery(String JavaDoc name,
507                                   NamedNativeQueryConfig queryConfig)
508     throws ConfigException
509   {
510     if (_namedNativeQueryMap.containsKey(name)) {
511       throw new ConfigException(L.l("NamedNativeQuery '{0}' is already defined.",
512                                     name));
513     }
514
515     _namedNativeQueryMap.put(name, queryConfig);
516   }
517
518   /**
519    * Returns the named native query.
520    */

521   public NamedNativeQueryConfig getNamedNativeQuery(String JavaDoc name)
522   {
523     return _namedNativeQueryMap.get(name);
524   }
525
526   /**
527    * Adds an entity.
528    */

529   public EntityType createEntity(JClass beanClass)
530   {
531     return createEntity(beanClass.getName(), beanClass);
532   }
533
534   /**
535    * Adds an entity.
536    */

537   public EntityType createEntity(String JavaDoc name,
538                                  JClass beanClass)
539   {
540     EntityType entityType = (EntityType) _typeManager.get(name);
541
542     if (entityType != null)
543       return entityType;
544
545     // ejb/0al2
546
// entityType = (EntityType) _typeManager.get(beanClass.getName());
547

548     if (entityType == null) {
549       EntityType parentType = null;
550
551       for (JClass parentClass = beanClass.getSuperClass();
552            parentType == null && parentClass != null;
553            parentClass = parentClass.getSuperClass()) {
554         parentType = (EntityType) _typeManager.get(parentClass.getName());
555       }
556
557       if (parentType != null)
558         entityType = new SubEntityType(this, parentType);
559       else
560         entityType = new EntityType(this);
561     }
562
563     // _typeManager.put(name, entityType);
564
_typeManager.put(name, entityType);
565     // XXX: some confusion about the double entry
566
if (_typeManager.get(beanClass.getName()) == null)
567       _typeManager.put(beanClass.getName(), entityType);
568
569     entityType.setName(name);
570     entityType.setBeanClass(beanClass);
571
572     _lazyConfigure.add(entityType);
573     // getEnvManager().addLazyConfigure(entityType);
574

575     AmberEntityHome entityHome = _entityHomeMap.get(beanClass.getName());
576
577     if (entityHome == null) {
578       entityHome = new AmberEntityHome(this, entityType);
579       _lazyHomeInit.add(entityHome);
580       _isInit = false;
581     }
582
583     addEntityHome(name, entityHome);
584     // XXX: some confusion about the double entry, related to the EJB 3.0
585
// confuction of named instances.
586
addEntityHome(beanClass.getName(), entityHome);
587
588     return entityType;
589   }
590
591   /**
592    * Adds an embeddable type.
593    */

594   public EmbeddableType createEmbeddable(String JavaDoc name,
595                                          JClass beanClass)
596   {
597     EmbeddableType embeddableType;
598
599     embeddableType = (EmbeddableType) _typeManager.get(name);
600
601     if (embeddableType != null)
602       return embeddableType;
603
604     embeddableType = new EmbeddableType(this);
605
606     _typeManager.put(name, embeddableType);
607
608     // XXX: some confusion about the double entry
609
if (_typeManager.get(beanClass.getName()) == null)
610       _typeManager.put(beanClass.getName(), embeddableType);
611
612     embeddableType.setName(name);
613     embeddableType.setBeanClass(beanClass);
614
615     _embeddableTypes.add(embeddableType);
616
617     return embeddableType;
618   }
619
620   /**
621    * Adds an enumerated type.
622    */

623   public EnumType createEnum(String JavaDoc name,
624                              JClass beanClass)
625   {
626     EnumType enumType = (EnumType) _typeManager.get(name);
627
628     if (enumType != null)
629       return enumType;
630
631     enumType = new EnumType();
632
633     _typeManager.put(name, enumType);
634
635     // XXX: some confusion about the double entry
636
if (_typeManager.get(beanClass.getName()) == null)
637       _typeManager.put(beanClass.getName(), enumType);
638
639     enumType.setName(name);
640     enumType.setBeanClass(beanClass);
641
642     return enumType;
643   }
644
645   /**
646    * Gets a default listener.
647    */

648   public ListenerType getDefaultListener(String JavaDoc className)
649   {
650     return _amberContainer.getDefaultListener(className);
651   }
652
653   /**
654    * Adds a default listener.
655    */

656   public ListenerType addDefaultListener(JClass beanClass)
657   {
658     ListenerType listenerType = getListener(beanClass);
659
660     if (! _defaultListeners.contains(listenerType)) {
661       _defaultListeners.add(listenerType);
662
663       _amberContainer.addDefaultListener(beanClass.getName(),
664                                          listenerType);
665     }
666
667     return listenerType;
668   }
669
670   /**
671    * Gets an entity listener.
672    */

673   public ListenerType getEntityListener(String JavaDoc className)
674   {
675     return _amberContainer.getEntityListener(className);
676   }
677
678   /**
679    * Adds an entity listener.
680    */

681   public ListenerType addEntityListener(String JavaDoc entityName,
682                                         JClass listenerClass)
683   {
684     ListenerType listenerType = getListener(listenerClass);
685
686     _amberContainer.addEntityListener(entityName,
687                                       listenerType);
688
689     return listenerType;
690   }
691
692   private ListenerType getListener(JClass beanClass)
693   {
694     String JavaDoc name = beanClass.getName();
695
696     ListenerType listenerType = (ListenerType) _typeManager.get(name);
697
698     if (listenerType != null)
699       return listenerType;
700
701     listenerType = new ListenerType(this);
702
703     ListenerType parentType = null;
704
705     for (JClass parentClass = beanClass.getSuperClass();
706          parentType == null && parentClass != null;
707          parentClass = parentClass.getSuperClass()) {
708       parentType = (ListenerType) _typeManager.get(parentClass.getName());
709     }
710
711     if (parentType != null)
712       listenerType = new SubListenerType(this, parentType);
713     else
714       listenerType = new ListenerType(this);
715
716     _typeManager.put(name, listenerType);
717
718     listenerType.setName(name);
719     listenerType.setBeanClass(beanClass);
720
721     return listenerType;
722   }
723
724   /**
725    * Adds a new home bean.
726    */

727   private void addEntityHome(String JavaDoc name, AmberEntityHome home)
728   {
729     _entityHomeMap.put(name, home);
730
731     // getEnvManager().addEntityHome(name, home);
732
}
733
734   /**
735    * Returns a table generator.
736    */

737   public IdGenerator getTableGenerator(String JavaDoc name)
738   {
739     return _tableGenMap.get(name);
740   }
741
742   /**
743    * Sets a table generator.
744    */

745   public IdGenerator putTableGenerator(String JavaDoc name, IdGenerator gen)
746   {
747     synchronized (_tableGenMap) {
748       IdGenerator oldGen = _tableGenMap.get(name);
749
750       if (oldGen != null)
751         return oldGen;
752       else {
753         _tableGenMap.put(name, gen);
754         return gen;
755       }
756     }
757   }
758
759   /**
760    * Adds a generator table.
761    */

762   public GeneratorTableType createGeneratorTable(String JavaDoc name)
763   {
764     Type type = _typeManager.get(name);
765
766     if (type instanceof GeneratorTableType)
767       return (GeneratorTableType) type;
768
769     if (type != null)
770       throw new RuntimeException JavaDoc(L.l("'{0}' is a duplicate generator table.",
771                                      type));
772
773     GeneratorTableType genType = new GeneratorTableType(this, name);
774
775     _typeManager.put(name, genType);
776
777     // _lazyGenerate.add(genType);
778

779     return genType;
780   }
781
782   /**
783    * Returns a sequence generator.
784    */

785   public SequenceIdGenerator createSequenceGenerator(String JavaDoc name, int size)
786     throws ConfigException
787   {
788     synchronized (_sequenceGenMap) {
789       SequenceIdGenerator gen = _sequenceGenMap.get(name);
790
791       if (gen == null) {
792         gen = new SequenceIdGenerator(this, name, size);
793
794         _sequenceGenMap.put(name, gen);
795       }
796
797       return gen;
798     }
799   }
800
801   /**
802    * Configures a type.
803    */

804   public void initType(AbstractEnhancedType type)
805     throws Exception JavaDoc
806   {
807     type.init();
808
809     getGenerator().generate(type);
810   }
811
812   /**
813    * Configure lazy.
814    */

815   public void generate()
816     throws Exception JavaDoc
817   {
818     configure();
819
820     AbstractEnhancedType type = null;
821
822     try {
823       while (_lazyGenerate.size() > 0) {
824         EntityType entityType = _lazyGenerate.remove(0);
825
826         // Entity
827
initType(type = entityType);
828
829         ArrayList JavaDoc<ListenerType> listeners;
830
831         String JavaDoc className = entityType.getBeanClass().getName();
832
833         listeners = _amberContainer.getEntityListeners(className);
834
835         if (listeners == null)
836           continue;
837
838         // Entity Listeners
839
for (ListenerType listenerType : listeners)
840           initType(type = listenerType);
841       }
842
843       // Embeddable
844
for (EmbeddableType embeddableType : _embeddableTypes)
845         initType(type = embeddableType);
846
847       // Default Listeners
848
for (ListenerType listenerType : _defaultListeners)
849         initType(type = listenerType);
850
851     } catch (Exception JavaDoc e) {
852       if (type != null) {
853         type.setConfigException(e);
854
855         _amberContainer.addEntityException(type.getBeanClass().getName(), e);
856       }
857
858       throw e;
859     }
860
861     try {
862       initTables();
863
864       getGenerator().compile();
865     } catch (Exception JavaDoc e) {
866       _amberContainer.addException(e);
867
868       throw e;
869     }
870   }
871
872   /**
873    * Gets the JPA flag.
874    */

875   public boolean isJPA()
876   {
877     return _isJPA;
878   }
879
880   /**
881    * Sets the JPA flag.
882    */

883   public void setJPA(boolean isJPA)
884   {
885     _isJPA = isJPA;
886   }
887
888   /**
889    * Configure lazy.
890    */

891   public void generate(JavaClassGenerator javaGen)
892     throws Exception JavaDoc
893   {
894     configure();
895
896     while (_lazyGenerate.size() > 0) {
897       EntityType type = _lazyGenerate.remove(0);
898
899       type.init();
900
901       if (type instanceof EntityType) {
902         EntityType entityType = (EntityType) type;
903
904         if (! entityType.isGenerated()) {
905           if (entityType.getInstanceClassName() == null)
906             throw new ConfigException(L.l("'{0}' does not have a configured instance class.",
907                                           entityType));
908
909           entityType.setGenerated(true);
910
911           try {
912             getGenerator().generateJava(javaGen, entityType);
913           } catch (Throwable JavaDoc e) {
914             log.log(Level.FINER, e.toString(), e);
915           }
916         }
917       }
918
919       configure();
920     }
921
922     for (EmbeddableType embeddableType : _embeddableTypes) {
923
924       embeddableType.init();
925
926       if (! embeddableType.isGenerated()) {
927         if (embeddableType.getInstanceClassName() == null)
928           throw new ConfigException(L.l("'{0}' does not have a configured instance class.",
929                                         embeddableType));
930
931         embeddableType.setGenerated(true);
932
933         try {
934           getGenerator().generateJava(javaGen, embeddableType);
935         } catch (Throwable JavaDoc e) {
936           log.log(Level.FINER, e.toString(), e);
937         }
938       }
939     }
940
941     for (SequenceIdGenerator gen : _sequenceGenMap.values())
942       gen.init(this);
943
944     while (_defaultListeners.size() > 0) {
945       ListenerType type = _defaultListeners.remove(0);
946
947       type.init();
948
949       if (! type.isGenerated()) {
950         if (type.getInstanceClassName() == null)
951           throw new ConfigException(L.l("'{0}' does not have a configured instance class.",
952                                         type));
953
954         type.setGenerated(true);
955
956         try {
957           getGenerator().generateJava(javaGen, type);
958         } catch (Throwable JavaDoc e) {
959           log.log(Level.FINER, e.toString(), e);
960         }
961       }
962     }
963   }
964
965   /**
966    * Returns the @Embeddable introspector.
967    */

968   public EmbeddableIntrospector getEmbeddableIntrospector()
969   {
970     return _embeddableIntrospector;
971   }
972
973   /**
974    * Configure lazy.
975    */

976   public void configure()
977     throws Exception JavaDoc
978   {
979     _embeddableIntrospector.configure();
980     _mappedSuperIntrospector.configure();
981
982     _entityIntrospector.configure();
983
984     while (_lazyConfigure.size() > 0) {
985       EntityType type = _lazyConfigure.remove(0);
986
987       if (type.startConfigure()) {
988         // getEnvManager().getGenerator().configure(type);
989
}
990
991       _entityIntrospector.configure();
992
993       if (! _lazyGenerate.contains(type))
994         _lazyGenerate.add(type);
995     }
996   }
997
998   /**
999    * Returns the entity home.
1000   */

1001  public AmberEntityHome getEntityHome(String JavaDoc name)
1002  {
1003    if (! _isInit) {
1004      try {
1005        initEntityHomes();
1006      } catch (RuntimeException JavaDoc e) {
1007        throw e;
1008      } catch (Exception JavaDoc e) {
1009        throw new AmberRuntimeException(e);
1010      }
1011    }
1012
1013    return _entityHomeMap.get(name);
1014  }
1015
1016  /**
1017   * Returns the entity home by the schema name.
1018   */

1019  public AmberEntityHome getHomeBySchema(String JavaDoc name)
1020  {
1021    for (AmberEntityHome home : _entityHomeMap.values()) {
1022      if (name.equals(home.getEntityType().getName()))
1023        return home;
1024    }
1025
1026    try {
1027      createType(name);
1028    } catch (Throwable JavaDoc e) {
1029    }
1030
1031    return _entityHomeMap.get(name);
1032  }
1033
1034  /**
1035   * Returns a matching embeddable type.
1036   */

1037  public EmbeddableType getEmbeddable(String JavaDoc className)
1038  {
1039    Type type = _typeManager.get(className);
1040
1041    if (type instanceof EmbeddableType)
1042      return (EmbeddableType) type;
1043    else
1044      return null;
1045  }
1046
1047  /**
1048   * Returns a matching entity.
1049   */

1050  public EntityType getEntity(String JavaDoc className)
1051  {
1052    Type type = _typeManager.get(className);
1053
1054    if (type instanceof EntityType)
1055      return (EntityType) type;
1056    else
1057      return null;
1058  }
1059
1060  /**
1061   * Returns a matching entity.
1062   */

1063  public EntityType getEntityByInstanceClass(String JavaDoc className)
1064  {
1065    return _typeManager.getEntityByInstanceClass(className);
1066  }
1067
1068  /**
1069   * Creates a type.
1070   */

1071  public Type createType(String JavaDoc typeName)
1072    throws ConfigException
1073  {
1074    Type type = _typeManager.get(typeName);
1075
1076    if (type != null)
1077      return type;
1078
1079    JClass cl = _amberContainer.getJClassLoader().forName(typeName);
1080
1081    if (cl == null)
1082      throw new ConfigException(L.l("'{0}' is an unknown type", typeName));
1083
1084    return createType(cl);
1085  }
1086
1087  /**
1088   * Creates a type.
1089   */

1090  public Type createType(JClass javaType)
1091    throws ConfigException
1092  {
1093    Type type = _typeManager.create(javaType);
1094
1095    if (type != null)
1096      return type;
1097
1098    return createEntity(javaType);
1099  }
1100
1101  /**
1102   * Sets the generator.
1103   */

1104  public AmberGenerator getGenerator()
1105  {
1106    if (_generator != null)
1107      return _generator;
1108    /*
1109      else if (_enhancer != null)
1110      return _enhancer;
1111    */

1112    else {
1113      _generator = _amberContainer.getGenerator();
1114
1115      return _generator;
1116    }
1117  }
1118
1119  /**
1120   * Returns true if generated keys are allowed.
1121   */

1122  public boolean hasReturnGeneratedKeys()
1123  {
1124    return getMetaData().supportsGetGeneratedKeys();
1125  }
1126
1127  /**
1128   * Sets the entity mappings config.
1129   */

1130  public void setEntityMappingsConfig(EntityMappingsConfig entityMappings)
1131  {
1132    _entityMappings = entityMappings;
1133
1134    if (_entityMappings != null) {
1135      _entityIntrospector.setEntityConfigMap(_entityMappings.getEntityMap());
1136      _entityIntrospector.setMappedSuperclassConfigMap(_entityMappings.getMappedSuperclassMap());
1137    }
1138  }
1139
1140  /**
1141   * Initialize the resource.
1142   */

1143  public void init()
1144    throws ConfigException, IOException JavaDoc
1145  {
1146    initLoaders();
1147
1148    if (_entityMappings != null) {
1149      BaseConfigIntrospector introspector = new BaseConfigIntrospector();
1150
1151      introspector.initMetaData(_entityMappings, this);
1152    }
1153
1154    if (_dataSource == null)
1155      return;
1156
1157    /*
1158    try {
1159      Connection conn = _dataSource.getConnection();
1160
1161      try {
1162        DatabaseMetaData metaData = conn.getMetaData();
1163
1164        try {
1165          _supportsGetGeneratedKeys = metaData.supportsGetGeneratedKeys();
1166        } catch (Throwable e) {
1167        }
1168      } finally {
1169        conn.close();
1170      }
1171    } catch (SQLException e) {
1172      throw new ConfigException(e);
1173    }
1174    */

1175  }
1176
1177  /**
1178   * Initialize the resource.
1179   */

1180  public void initLoaders()
1181    throws ConfigException, IOException JavaDoc
1182  {
1183    // getEnvManager().initLoaders();
1184
}
1185
1186  public void initEntityHomes()
1187    throws AmberException, ConfigException
1188  {
1189    synchronized (this) {
1190      if (_isInit)
1191        return;
1192      _isInit = true;
1193    }
1194
1195    initTables();
1196
1197    while (_lazyHomeInit.size() > 0) {
1198      AmberEntityHome home = _lazyHomeInit.remove(0);
1199
1200      home.init();
1201    }
1202  }
1203
1204  /**
1205   * Configure lazy.
1206   */

1207  public void initTables()
1208    throws ConfigException
1209  {
1210    while (_lazyTable.size() > 0) {
1211      Table table = _lazyTable.remove(0);
1212
1213      if (getDataSource() == null)
1214        throw new ConfigException(L.l("No configured data-source found for <ejb-server>."));
1215
1216      if (getCreateDatabaseTables())
1217        table.createDatabaseTable(this);
1218
1219      if (getValidateDatabaseTables())
1220        table.validateDatabaseTable(this);
1221    }
1222  }
1223
1224  /**
1225   * Returns the cache connection.
1226   */

1227  public CacheConnection getCacheConnection()
1228  {
1229    // cache connection cannot be reused (#998)
1230

1231    CacheConnection cacheConnection = new CacheConnection(this);
1232
1233    // ejb/0a0b - avoid dangling connections.
1234
cacheConnection.register();
1235
1236    return cacheConnection;
1237  }
1238
1239  /**
1240   * Returns the cache connection.
1241   */

1242  public AmberConnection createAmberConnection()
1243  {
1244    return new AmberConnection(this);
1245  }
1246
1247  /**
1248   * Returns the thread's amber connection.
1249   */

1250  public AmberConnection getThreadConnection()
1251  {
1252    AmberConnection aConn = _threadConnection.get();
1253
1254    if (aConn == null) {
1255      aConn = new AmberConnection(this);
1256      aConn.initThreadConnection();
1257
1258      _threadConnection.set(aConn);
1259    }
1260
1261    return aConn;
1262  }
1263
1264  /**
1265   * Unset the thread's amber connection.
1266   */

1267  public void removeThreadConnection()
1268  {
1269    _threadConnection.set(null);
1270  }
1271
1272  /**
1273   * Returns an EntityHome.
1274   */

1275  public AmberEntityHome getHome(Class JavaDoc cl)
1276  {
1277    return getEntityHome(cl.getName());
1278  }
1279
1280  /**
1281   * Returns the query result.
1282   */

1283  public ResultSetCacheChunk getQueryChunk(QueryCacheKey key)
1284  {
1285    SoftReference JavaDoc<ResultSetCacheChunk> ref = _queryCache.get(key);
1286
1287    if (ref == null)
1288      return null;
1289    else {
1290      ResultSetCacheChunk chunk = ref.get();
1291
1292      if (chunk != null && chunk.isValid())
1293        return chunk;
1294      else
1295        return null;
1296    }
1297  }
1298
1299  /**
1300   * Returns the query meta data.
1301   */

1302  public ResultSetMetaData JavaDoc getQueryMetaData(QueryCacheKey key)
1303  {
1304    SoftReference JavaDoc<ResultSetMetaData JavaDoc> ref = _queryCacheMetaData.get(key);
1305
1306    if (ref == null)
1307      return null;
1308    else
1309      return ref.get();
1310  }
1311
1312  /**
1313   * Applies persistence unit default and entity listeners
1314   * for @PreXxx, @PostXxx callbacks.
1315   */

1316  protected void callListeners(int callbackIndex,
1317                               Entity entity)
1318  {
1319    // ejb/0g22
1320
if (! isJPA())
1321      return;
1322
1323    String JavaDoc className = entity.getClass().getName();
1324
1325    EntityType entityType = (EntityType) _typeManager.get(className);
1326
1327    if (! entityType.getExcludeDefaultListeners()) {
1328      for (ListenerType listenerType : _defaultListeners) {
1329        for (JMethod m : listenerType.getCallbacks(callbackIndex)) {
1330          Listener listener = (Listener) listenerType.getInstance();
1331          listener.__caucho_callback(callbackIndex, entity);
1332        }
1333      }
1334    }
1335
1336    ArrayList JavaDoc<ListenerType> listeners;
1337
1338    listeners = _amberContainer.getEntityListeners(className);
1339
1340    if (listeners == null)
1341      return;
1342
1343    for (ListenerType listenerType : listeners) {
1344
1345      if ((! entityType.getExcludeDefaultListeners()) &&
1346          _defaultListeners.contains(listenerType))
1347        continue;
1348
1349      for (JMethod m : listenerType.getCallbacks(callbackIndex)) {
1350        Listener listener = (Listener) listenerType.getInstance();
1351        listener.__caucho_callback(callbackIndex, entity);
1352      }
1353    }
1354  }
1355
1356  /**
1357   * Sets the query result.
1358   */

1359  public void putQueryChunk(QueryCacheKey key, ResultSetCacheChunk chunk)
1360  {
1361    _queryCache.put(key, new SoftReference JavaDoc<ResultSetCacheChunk>(chunk));
1362  }
1363
1364  /**
1365   * Sets the query meta data.
1366   */

1367  public void putQueryMetaData(QueryCacheKey key, ResultSetMetaData JavaDoc metaData)
1368  {
1369    _queryCacheMetaData.put(key, new SoftReference JavaDoc<ResultSetMetaData JavaDoc>(metaData));
1370  }
1371
1372  /**
1373   * Returns the entity item.
1374   */

1375  public EntityItem getEntityItem(String JavaDoc homeName, Object JavaDoc key)
1376    throws AmberException
1377  {
1378    AmberEntityHome home = getEntityHome(homeName);
1379
1380    return home.findEntityItem(getCacheConnection(), key, false);
1381  }
1382
1383  /**
1384   * Returns the entity with the given key.
1385   */

1386  public EntityItem getEntity(EntityType rootType, Object JavaDoc key)
1387  {
1388    SoftReference JavaDoc<EntityItem> ref;
1389
1390    synchronized (_entityKey) {
1391      _entityKey.init(rootType, key);
1392      ref = _entityCache.get(_entityKey);
1393    }
1394
1395    if (ref != null)
1396      return ref.get();
1397    else
1398      return null;
1399  }
1400
1401  /**
1402   * Sets the entity result.
1403   */

1404  public EntityItem putEntity(EntityType rootType,
1405                              Object JavaDoc key,
1406                              EntityItem entity)
1407  {
1408    SoftReference JavaDoc<EntityItem> ref = new SoftReference JavaDoc<EntityItem>(entity);
1409    EntityKey entityKey = new EntityKey(rootType, key);
1410
1411    ref = _entityCache.putIfNew(entityKey, ref);
1412
1413    return ref.get();
1414  }
1415
1416  /**
1417   * Remove the entity result.
1418   */

1419  public EntityItem removeEntity(EntityType rootType, Object JavaDoc key)
1420  {
1421    SoftReference JavaDoc<EntityItem> ref;
1422
1423    synchronized (_entityKey) {
1424      _entityKey.init(rootType, key);
1425      ref = _entityCache.remove(_entityKey);
1426    }
1427
1428    if (ref != null)
1429      return ref.get();
1430    else
1431      return null;
1432  }
1433
1434  /**
1435   * Completions affecting the cache.
1436   */

1437  public void complete(ArrayList JavaDoc<AmberCompletion> completions)
1438  {
1439    int size = completions.size();
1440    if (size == 0)
1441      return;
1442
1443    synchronized (_entityCache) {
1444      Iterator JavaDoc<LruCache.Entry<EntityKey,SoftReference JavaDoc<EntityItem>>> iter;
1445
1446      iter = _entityCache.iterator();
1447      while (iter.hasNext()) {
1448        LruCache.Entry<EntityKey,SoftReference JavaDoc<EntityItem>> entry;
1449        entry = iter.next();
1450
1451        EntityKey key = entry.getKey();
1452        SoftReference JavaDoc<EntityItem> valueRef = entry.getValue();
1453        EntityItem value = valueRef.get();
1454
1455        if (value == null)
1456          continue;
1457
1458        EntityType entityRoot = key.getEntityType();
1459        Object JavaDoc entityKey = key.getKey();
1460
1461        for (int i = 0; i < size; i++) {
1462          if (completions.get(i).complete(entityRoot, entityKey, value)) {
1463            // XXX: delete
1464
}
1465        }
1466      }
1467    }
1468
1469    synchronized (_queryCache) {
1470      Iterator JavaDoc<SoftReference JavaDoc<ResultSetCacheChunk>> iter;
1471
1472      iter = _queryCache.values();
1473      while (iter.hasNext()) {
1474        SoftReference JavaDoc<ResultSetCacheChunk> ref = iter.next();
1475
1476        ResultSetCacheChunk chunk = ref.get();
1477
1478        if (chunk != null) {
1479          for (int i = 0; i < size; i++) {
1480            if (completions.get(i).complete(chunk)) {
1481              // XXX: delete
1482
}
1483          }
1484        }
1485      }
1486    }
1487  }
1488
1489  /**
1490   * destroys the manager.
1491   */

1492  public void destroy()
1493  {
1494    _typeManager = null;
1495    _queryCache = null;
1496    _entityCache = null;
1497  }
1498
1499  /**
1500   * New Version of getCreateTableSQL which returns
1501   * the SQL for the table with the given SQL type
1502   * but takes sqlType, length, precision, and scale.
1503   */

1504  public String JavaDoc getCreateColumnSQL(int sqlType, int length, int precision, int scale) {
1505    return getMetaData().getCreateColumnSQL(sqlType, length, precision, scale);
1506  }
1507
1508  /*
1509  public String toString()
1510  {
1511    return "AmberPersistenceUnit[" + _defaultListeners + "]";
1512  }
1513  */

1514}
1515
Popular Tags