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