KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > cfg > Configuration


1 //$Id: Configuration.java,v 1.79 2005/07/21 01:11:50 oneovthafew Exp $
2
package org.hibernate.cfg;
3
4 import java.io.File JavaDoc;
5 import java.io.FileInputStream JavaDoc;
6 import java.io.FileNotFoundException JavaDoc;
7 import java.io.FileOutputStream JavaDoc;
8 import java.io.IOException JavaDoc;
9 import java.io.InputStream JavaDoc;
10 import java.io.ObjectInputStream JavaDoc;
11 import java.io.Serializable JavaDoc;
12 import java.io.StringReader JavaDoc;
13 import java.net.URL JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.Enumeration JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.Properties JavaDoc;
22 import java.util.Set JavaDoc;
23 import java.util.TreeMap JavaDoc;
24 import java.util.Map.Entry;
25 import java.util.jar.JarFile JavaDoc;
26 import java.util.zip.ZipEntry JavaDoc;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.dom4j.Attribute;
31 import org.dom4j.DocumentException;
32 import org.dom4j.Element;
33 import org.hibernate.EmptyInterceptor;
34 import org.hibernate.HibernateException;
35 import org.hibernate.Interceptor;
36 import org.hibernate.MappingException;
37 import org.hibernate.SessionFactory;
38 import org.hibernate.dialect.Dialect;
39 import org.hibernate.dialect.MySQLDialect;
40 import org.hibernate.engine.FilterDefinition;
41 import org.hibernate.engine.Mapping;
42 import org.hibernate.event.AutoFlushEventListener;
43 import org.hibernate.event.PersistEventListener;
44 import org.hibernate.event.DeleteEventListener;
45 import org.hibernate.event.DirtyCheckEventListener;
46 import org.hibernate.event.EvictEventListener;
47 import org.hibernate.event.FlushEntityEventListener;
48 import org.hibernate.event.FlushEventListener;
49 import org.hibernate.event.InitializeCollectionEventListener;
50 import org.hibernate.event.LoadEventListener;
51 import org.hibernate.event.LockEventListener;
52 import org.hibernate.event.MergeEventListener;
53 import org.hibernate.event.PostDeleteEventListener;
54 import org.hibernate.event.PostInsertEventListener;
55 import org.hibernate.event.PostLoadEventListener;
56 import org.hibernate.event.PostUpdateEventListener;
57 import org.hibernate.event.PreDeleteEventListener;
58 import org.hibernate.event.PreInsertEventListener;
59 import org.hibernate.event.PreLoadEventListener;
60 import org.hibernate.event.PreUpdateEventListener;
61 import org.hibernate.event.RefreshEventListener;
62 import org.hibernate.event.ReplicateEventListener;
63 import org.hibernate.event.SaveOrUpdateEventListener;
64 import org.hibernate.event.SessionEventListenerConfig;
65 import org.hibernate.id.IdentifierGenerator;
66 import org.hibernate.id.PersistentIdentifierGenerator;
67 import org.hibernate.impl.SessionFactoryImpl;
68 import org.hibernate.mapping.Collection;
69 import org.hibernate.mapping.ForeignKey;
70 import org.hibernate.mapping.IdentifierCollection;
71 import org.hibernate.mapping.Index;
72 import org.hibernate.mapping.PersistentClass;
73 import org.hibernate.mapping.Property;
74 import org.hibernate.mapping.RootClass;
75 import org.hibernate.mapping.SimpleValue;
76 import org.hibernate.mapping.Table;
77 import org.hibernate.mapping.UniqueKey;
78 import org.hibernate.secure.JACCConfiguration;
79 import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
80 import org.hibernate.tool.hbm2ddl.TableMetadata;
81 import org.hibernate.type.SerializationException;
82 import org.hibernate.type.Type;
83 import org.hibernate.util.ArrayHelper;
84 import org.hibernate.util.CollectionHelper;
85 import org.hibernate.util.SerializationHelper;
86 import org.hibernate.util.XMLHelper;
87 import org.hibernate.util.ReflectHelper;
88 import org.w3c.dom.Document JavaDoc;
89 import org.xml.sax.EntityResolver JavaDoc;
90 import org.xml.sax.InputSource JavaDoc;
91
92 /**
93  * An instance of <tt>Configuration</tt> allows the application
94  * to specify properties and mapping documents to be used when
95  * creating a <tt>SessionFactory</tt>. Usually an application will create
96  * a single <tt>Configuration</tt>, build a single instance of
97  * <tt>SessionFactory</tt> and then instantiate <tt>Session</tt>s in
98  * threads servicing client requests. The <tt>Configuration</tt> is meant
99  * only as an initialization-time object. <tt>SessionFactory</tt>s are
100  * immutable and do not retain any association back to the
101  * <tt>Configuration</tt>.<br>
102  * <br>
103  * A new <tt>Configuration</tt> will use the properties specified in
104  * <tt>hibernate.properties</tt> by default.
105  *
106  * @author Gavin King
107  * @see org.hibernate.SessionFactory
108  */

109 public class Configuration implements Serializable JavaDoc {
110
111     private static Log log = LogFactory.getLog( Configuration.class );
112
113     protected Map JavaDoc classes;
114     protected Map JavaDoc imports;
115     protected Map JavaDoc collections;
116     protected Map JavaDoc tables;
117     protected Map JavaDoc namedQueries;
118     protected Map JavaDoc namedSqlQueries;
119     /** Map<String, SqlResultSetMapping> result set name, result set description */
120     protected Map JavaDoc sqlResultSetMappings;
121     protected Map JavaDoc filterDefinitions;
122     protected List JavaDoc secondPasses;
123     protected List JavaDoc propertyReferences;
124     protected Map JavaDoc extendsQueue; // key: classname -> value: dom4j document
125
private Interceptor interceptor;
126     private Properties JavaDoc properties;
127     private EntityResolver JavaDoc entityResolver;
128
129     private transient XMLHelper xmlHelper;
130     protected transient Map JavaDoc typeDefs;
131
132     protected NamingStrategy namingStrategy = DefaultNamingStrategy.INSTANCE;
133
134     private SessionEventListenerConfig sessionEventListenerConfig;
135
136     protected final SettingsFactory settingsFactory;
137
138     protected void reset() {
139         classes = new HashMap JavaDoc();
140         imports = new HashMap JavaDoc();
141         collections = new HashMap JavaDoc();
142         tables = new TreeMap JavaDoc();
143         namedQueries = new HashMap JavaDoc();
144         namedSqlQueries = new HashMap JavaDoc();
145         sqlResultSetMappings = new HashMap JavaDoc();
146         xmlHelper = new XMLHelper();
147         typeDefs = new HashMap JavaDoc();
148         propertyReferences = new ArrayList JavaDoc();
149         secondPasses = new ArrayList JavaDoc();
150         interceptor = EmptyInterceptor.INSTANCE;
151         properties = Environment.getProperties();
152         entityResolver = XMLHelper.DEFAULT_DTD_RESOLVER;
153         sessionEventListenerConfig = new SessionEventListenerConfig();
154         filterDefinitions = new HashMap JavaDoc();
155         extendsQueue = new HashMap JavaDoc();
156     }
157
158     private transient Mapping mapping = buildMapping();
159
160     protected Configuration(SettingsFactory settingsFactory) {
161         this.settingsFactory = settingsFactory;
162         reset();
163     }
164
165     public Configuration() {
166         this( new SettingsFactory() );
167     }
168
169     /**
170      * Iterate the class mappings
171      */

172     public Iterator JavaDoc getClassMappings() {
173         return classes.values().iterator();
174     }
175
176     /**
177      * Iterate the collection mappings
178      */

179     public Iterator JavaDoc getCollectionMappings() {
180         return collections.values().iterator();
181     }
182
183     /**
184      * Iterate the table mappings
185      */

186     public Iterator JavaDoc getTableMappings() {
187         return tables.values().iterator();
188     }
189
190     /**
191      * Get the mapping for a particular class
192      */

193     public PersistentClass getClassMapping(String JavaDoc persistentClass) {
194         return ( PersistentClass ) classes.get( persistentClass );
195     }
196
197     /**
198      * Get the mapping for a particular collection role
199      *
200      * @param role a collection role
201      * @return Collection
202      */

203     public Collection getCollectionMapping(String JavaDoc role) {
204         return ( Collection ) collections.get( role );
205     }
206
207     /**
208      * Set a custom entity resolver. This entity resolver must be
209      * set before addXXX(misc) call.
210      * Default value is {@link org.hibernate.util.DTDEntityResolver}
211      *
212      * @param entityResolver entity resolver to use
213      */

214     public void setEntityResolver(EntityResolver JavaDoc entityResolver) {
215         this.entityResolver = entityResolver;
216     }
217
218     /**
219      * Read mappings from a particular XML file
220      *
221      * @param xmlFile a path to a file
222      */

223     public Configuration addFile(String JavaDoc xmlFile) throws MappingException {
224         log.info( "Reading mappings from file: " + xmlFile );
225         try {
226             List JavaDoc errors = new ArrayList JavaDoc();
227             org.dom4j.Document doc = xmlHelper.createSAXReader( xmlFile, errors, entityResolver )
228                     .read( new File JavaDoc( xmlFile ) );
229             if ( errors.size() != 0 ) {
230                 throw new MappingException( "invalid mapping", ( Throwable JavaDoc ) errors.get( 0 ) );
231             }
232             add( doc );
233             return this;
234         }
235         catch ( Exception JavaDoc e ) {
236             throw new MappingException(
237                     "Could not read mapping document from file: " + xmlFile,
238                     e
239                 );
240         }
241     }
242
243     /**
244      * Read mappings from a particular XML file
245      *
246      * @param xmlFile a path to a file
247      */

248     public Configuration addFile(File JavaDoc xmlFile) throws MappingException {
249         log.info( "Reading mappings from file: " + xmlFile.getPath() );
250         try {
251             addInputStream( new FileInputStream JavaDoc( xmlFile ) );
252         }
253         catch ( Exception JavaDoc e ) {
254             throw new MappingException(
255                     "Could not read mapping document from file: " + xmlFile.getPath(),
256                     e
257                 );
258         }
259         return this;
260     }
261
262     /**
263      * If a cached <tt>xmlFile + ".bin"</tt> exists and is newer than <tt>xmlFile</tt> the
264      * <tt>".bin"</tt> file will be read directly. Otherwise xmlFile is read and then
265      * serialized to <tt>xmlFile + ".bin"</tt> for use the next time.
266      */

267     public Configuration addCacheableFile(File JavaDoc xmlFile) throws MappingException {
268         try {
269             File JavaDoc lazyfile = new File JavaDoc( xmlFile.getAbsolutePath() + ".bin" );
270             org.dom4j.Document doc = null;
271             List JavaDoc errors = new ArrayList JavaDoc();
272
273             final boolean useCachedFile = xmlFile.exists() &&
274                     lazyfile.exists() &&
275                     xmlFile.lastModified() < lazyfile.lastModified();
276
277             if ( useCachedFile ) {
278                 try {
279                     log.info( "Reading mappings from cache file: " + lazyfile );
280                     doc = ( org.dom4j.Document ) SerializationHelper.deserialize( new FileInputStream JavaDoc( lazyfile ) );
281                 }
282                 catch ( SerializationException e ) {
283                     log.warn( "Could not deserialize cache file: " + lazyfile.getPath(), e );
284                 }
285             }
286
287             // If deserialization failed
288
if ( doc == null ) {
289                 log.info( "Reading mappings from file: " + xmlFile );
290                 doc = xmlHelper.createSAXReader( xmlFile.getAbsolutePath(), errors, entityResolver )
291                         .read( xmlFile );
292                 try {
293                     log.debug( "Writing cache file for: " + xmlFile + " to: " + lazyfile );
294                     SerializationHelper.serialize( ( Serializable JavaDoc ) doc, new FileOutputStream JavaDoc( lazyfile ) );
295                 }
296                 catch ( SerializationException e ) {
297                     log.warn( "Could not write cached file: " + lazyfile, e );
298                 }
299             }
300
301             if ( errors.size() != 0 ) {
302                 throw new MappingException( "invalid mapping", ( Throwable JavaDoc ) errors.get( 0 ) );
303             }
304             add( doc );
305             return this;
306         }
307         catch ( Exception JavaDoc e ) {
308             throw new MappingException(
309                     "Could not read mapping document from file: " + xmlFile,
310                     e
311                 );
312         }
313     }
314
315     public Configuration addCacheableFile(String JavaDoc xmlFile) throws MappingException {
316         return addCacheableFile( new File JavaDoc( xmlFile ) );
317     }
318
319
320     /**
321      * Read mappings from a <tt>String</tt>
322      *
323      * @param xml an XML string
324      */

325     public Configuration addXML(String JavaDoc xml) throws MappingException {
326         if ( log.isDebugEnabled() ) log.debug( "Mapping XML:\n" + xml );
327         try {
328             List JavaDoc errors = new ArrayList JavaDoc();
329             org.dom4j.Document doc = xmlHelper.createSAXReader( "XML String", errors, entityResolver )
330                     .read( new StringReader JavaDoc( xml ) );
331             if ( errors.size() != 0 ) {
332                 throw new MappingException( "invalid mapping", ( Throwable JavaDoc ) errors.get( 0 ) );
333             }
334             add( doc );
335         }
336         catch ( DocumentException e ) {
337             throw new MappingException( "Could not parse mapping document in XML string", e );
338         }
339         return this;
340     }
341
342     /**
343      * Read mappings from a <tt>URL</tt>
344      *
345      * @param url
346      */

347     public Configuration addURL(URL JavaDoc url) throws MappingException {
348         if ( log.isDebugEnabled() ) log.debug( "Reading mapping document from URL:" + url );
349         try {
350             addInputStream( url.openStream() );
351         }
352         catch ( Exception JavaDoc e ) {
353             throw new MappingException( "Could not read mapping document from URL: " + url, e );
354         }
355         return this;
356     }
357
358     /**
359      * Read mappings from a DOM <tt>Document</tt>
360      *
361      * @param doc a DOM document
362      */

363     public Configuration addDocument(Document JavaDoc doc) throws MappingException {
364         if ( log.isDebugEnabled() ) log.debug( "Mapping document:\n" + doc );
365         add( xmlHelper.createDOMReader().read( doc ) );
366         return this;
367     }
368
369     protected void add(org.dom4j.Document doc) throws MappingException {
370         HbmBinder.bindRoot( doc, createMappings(), CollectionHelper.EMPTY_MAP );
371         // TODO: possibly get inheritable meta's from cfg.xml
372
}
373
374     /**
375      * Create a new <tt>Mappings</tt> to add class and collection
376      * mappings to.
377      */

378     public Mappings createMappings() {
379         return new Mappings(
380                 classes,
381                 collections,
382                 tables,
383                 namedQueries,
384                 namedSqlQueries,
385                 sqlResultSetMappings,
386                 imports,
387                 secondPasses,
388                 propertyReferences,
389                 namingStrategy,
390                 typeDefs,
391                 filterDefinitions,
392                 extendsQueue
393             );
394     }
395
396     /**
397      * Read mappings from an <tt>InputStream</tt>
398      *
399      * @param xmlInputStream an <tt>InputStream</tt> containing XML
400      */

401     public Configuration addInputStream(InputStream JavaDoc xmlInputStream) throws MappingException {
402         try {
403             List JavaDoc errors = new ArrayList JavaDoc();
404             org.dom4j.Document doc = xmlHelper.createSAXReader( "XML InputStream", errors, entityResolver )
405                     .read( new InputSource JavaDoc( xmlInputStream ) );
406             if ( errors.size() != 0 ) {
407                 throw new MappingException( "invalid mapping", ( Throwable JavaDoc ) errors.get( 0 ) );
408             }
409             add( doc );
410             return this;
411         }
412         catch ( DocumentException e ) {
413             throw new MappingException( "Could not parse mapping document in input stream", e );
414         }
415         finally {
416             try {
417                 xmlInputStream.close();
418             }
419             catch ( IOException JavaDoc ioe ) {
420                 log.warn( "Could not close input stream", ioe );
421             }
422         }
423     }
424
425     /**
426      * Read mappings from an application resource
427      *
428      * @param path a resource
429      * @param classLoader a <tt>ClassLoader</tt> to use
430      */

431     public Configuration addResource(String JavaDoc path, ClassLoader JavaDoc classLoader) throws MappingException {
432         log.info( "Reading mappings from resource: " + path );
433         InputStream JavaDoc rsrc = classLoader.getResourceAsStream( path );
434         if ( rsrc == null ) {
435             throw new MappingException( "Resource: " + path + " not found" );
436         }
437         try {
438             return addInputStream( rsrc );
439         }
440         catch ( MappingException me ) {
441             throw new MappingException( "Could not read mappings from resource: " + path, me );
442         }
443     }
444
445     /**
446      * Read mappings from an application resource trying different classloaders.
447      * This method will try to load the resource first from the thread context
448      * classloader and then from the classloader that loaded Hibernate.
449      */

450     public Configuration addResource(String JavaDoc path) throws MappingException {
451         log.info( "Reading mappings from resource: " + path );
452         InputStream JavaDoc rsrc = Thread.currentThread().getContextClassLoader().getResourceAsStream( path );
453         if ( rsrc == null ) {
454             rsrc = Environment.class.getClassLoader().getResourceAsStream( path );
455         }
456         if ( rsrc == null ) {
457             throw new MappingException( "Resource: " + path + " not found" );
458         }
459         try {
460             return addInputStream( rsrc );
461         }
462         catch ( MappingException me ) {
463             throw new MappingException( "Could not read mappings from resource: " + path, me );
464         }
465     }
466
467     /**
468      * Read a mapping from an application resource, using a convention.
469      * The class <tt>foo.bar.Foo</tt> is mapped by the file <tt>foo/bar/Foo.hbm.xml</tt>.
470      *
471      * @param persistentClass the mapped class
472      */

473     public Configuration addClass(Class JavaDoc persistentClass) throws MappingException {
474         String JavaDoc fileName = persistentClass.getName().replace( '.', '/' ) + ".hbm.xml";
475         log.info( "Reading mappings from resource: " + fileName );
476         InputStream JavaDoc rsrc = persistentClass.getClassLoader().getResourceAsStream( fileName );
477         if ( rsrc == null ) {
478             throw new MappingException( "Resource: " + fileName + " not found" );
479         }
480         try {
481             return addInputStream( rsrc );
482         }
483         catch ( MappingException me ) {
484             throw new MappingException(
485                     "Could not read mappings from resource: " + fileName,
486                     me
487                 );
488         }
489     }
490
491     /**
492      * Read all mappings from a jar file
493      *
494      * @param jar a jar file
495      */

496     public Configuration addJar(File JavaDoc jar) throws MappingException {
497
498         log.info( "Searching for mapping documents in jar: " + jar.getName() );
499
500         final JarFile JavaDoc jarFile;
501         try {
502             jarFile = new JarFile JavaDoc( jar );
503         }
504         catch ( IOException JavaDoc ioe ) {
505             throw new MappingException(
506                     "Could not read mapping documents from jar: " + jar.getName(),
507                     ioe
508                 );
509         }
510
511         Enumeration JavaDoc jarEntries = jarFile.entries();
512         while ( jarEntries.hasMoreElements() ) {
513
514             ZipEntry JavaDoc ze = ( ZipEntry JavaDoc ) jarEntries.nextElement();
515
516             if ( ze.getName().endsWith( ".hbm.xml" ) ) {
517                 log.info( "Found mapping document in jar: " + ze.getName() );
518                 try {
519                     addInputStream( jarFile.getInputStream( ze ) );
520                 }
521                 catch ( Exception JavaDoc e ) {
522                     throw new MappingException(
523                             "Could not read mapping documents from jar: " + jar.getName(),
524                             e
525                         );
526                 }
527             }
528         }
529
530         return this;
531
532     }
533
534     /**
535      * Read all mapping documents from a directory tree. Assume that any
536      * file named <tt>*.hbm.xml</tt> is a mapping document.
537      *
538      * @param dir a directory
539      */

540     public Configuration addDirectory(File JavaDoc dir) throws MappingException {
541         File JavaDoc[] files = dir.listFiles();
542         for ( int i = 0; i < files.length; i++ ) {
543             if ( files[i].isDirectory() ) {
544                 addDirectory( files[i] );
545             }
546             else if ( files[i].getName().endsWith( ".hbm.xml" ) ) {
547                 addFile( files[i] );
548             }
549         }
550         return this;
551     }
552
553     private Iterator JavaDoc iterateGenerators(Dialect dialect) throws MappingException {
554
555         TreeMap JavaDoc generators = new TreeMap JavaDoc();
556         String JavaDoc defaultCatalog = properties.getProperty(Environment.DEFAULT_CATALOG);
557         String JavaDoc defaultSchema = properties.getProperty(Environment.DEFAULT_SCHEMA);
558
559         Iterator JavaDoc iter = classes.values().iterator();
560         while ( iter.hasNext() ) {
561             PersistentClass pc = ( PersistentClass ) iter.next();
562
563             if ( !pc.isInherited() ) {
564
565                 IdentifierGenerator ig = pc.getIdentifier()
566                     .createIdentifierGenerator(
567                             dialect,
568                             defaultCatalog,
569                             defaultSchema,
570                             (RootClass) pc
571                         );
572
573                 if ( ig instanceof PersistentIdentifierGenerator ) {
574                     generators.put( ( ( PersistentIdentifierGenerator ) ig ).generatorKey(), ig );
575                 }
576
577             }
578         }
579
580         iter = collections.values().iterator();
581         while ( iter.hasNext() ) {
582             Collection collection = ( Collection ) iter.next();
583
584             if ( collection.isIdentified() ) {
585
586                 IdentifierGenerator ig = ( ( IdentifierCollection ) collection ).getIdentifier()
587                         .createIdentifierGenerator(
588                                 dialect,
589                                 defaultCatalog,
590                                 defaultSchema,
591                                 null
592                             );
593
594                 if ( ig instanceof PersistentIdentifierGenerator ) {
595                     generators.put( ( ( PersistentIdentifierGenerator ) ig ).generatorKey(), ig );
596                 }
597
598             }
599         }
600
601         return generators.values().iterator();
602     }
603
604     /**
605      * Generate DDL for dropping tables
606      *
607      * @see org.hibernate.tool.hbm2ddl.SchemaExport
608      */

609     public String JavaDoc[] generateDropSchemaScript(Dialect dialect) throws HibernateException {
610
611         secondPassCompile();
612
613         String JavaDoc defaultCatalog = properties.getProperty(Environment.DEFAULT_CATALOG);
614         String JavaDoc defaultSchema = properties.getProperty(Environment.DEFAULT_SCHEMA);
615
616         ArrayList JavaDoc script = new ArrayList JavaDoc( 50 );
617
618         if ( dialect.dropConstraints() ) {
619             Iterator JavaDoc iter = getTableMappings();
620             while ( iter.hasNext() ) {
621                 Table table = ( Table ) iter.next();
622                 if ( table.isPhysicalTable() ) {
623                     Iterator JavaDoc subIter = table.getForeignKeyIterator();
624                     while ( subIter.hasNext() ) {
625                         ForeignKey fk = ( ForeignKey ) subIter.next();
626                         if ( fk.isPhysicalConstraint() ) {
627                             script.add( fk.sqlDropString(
628                                     dialect,
629                                     defaultCatalog,
630                                     defaultSchema ) );
631                         }
632                     }
633                 }
634             }
635         }
636
637
638         Iterator JavaDoc iter = getTableMappings();
639         while ( iter.hasNext() ) {
640
641             Table table = ( Table ) iter.next();
642             if ( table.isPhysicalTable() ) {
643
644                 /*Iterator subIter = table.getIndexIterator();
645                 while ( subIter.hasNext() ) {
646                     Index index = (Index) subIter.next();
647                     if ( !index.isForeignKey() || !dialect.hasImplicitIndexForForeignKey() ) {
648                         script.add( index.sqlDropString(dialect) );
649                     }
650                 }*/

651     
652                 script.add( table.sqlDropString(
653                         dialect,
654                         defaultCatalog,
655                         defaultSchema ) );
656
657             }
658
659         }
660
661         iter = iterateGenerators( dialect );
662         while ( iter.hasNext() ) {
663             String JavaDoc[] lines = ( ( PersistentIdentifierGenerator ) iter.next() ).sqlDropStrings( dialect );
664             for ( int i = 0; i < lines.length; i++ ) script.add( lines[i] );
665         }
666
667         return ArrayHelper.toStringArray( script );
668     }
669
670     /**
671      * Generate DDL for creating tables
672      *
673      * @see org.hibernate.tool.hbm2ddl.SchemaExport
674      */

675     public String JavaDoc[] generateSchemaCreationScript(Dialect dialect) throws HibernateException {
676         secondPassCompile();
677
678         ArrayList JavaDoc script = new ArrayList JavaDoc( 50 );
679         String JavaDoc defaultCatalog = properties.getProperty(Environment.DEFAULT_CATALOG);
680         String JavaDoc defaultSchema = properties.getProperty(Environment.DEFAULT_SCHEMA);
681
682         Iterator JavaDoc iter = getTableMappings();
683         while ( iter.hasNext() ) {
684             Table table = ( Table ) iter.next();
685             if ( table.isPhysicalTable() ) {
686                 script.add( table.sqlCreateString(
687                         dialect,
688                         mapping,
689                         defaultCatalog,
690                         defaultSchema ) );
691                 Iterator JavaDoc comments = table.sqlCommentStrings(dialect, defaultCatalog, defaultSchema);
692                 while ( comments.hasNext() ) {
693                     script.add( comments.next() );
694                 }
695             }
696         }
697
698         iter = getTableMappings();
699         while ( iter.hasNext() ) {
700             Table table = ( Table ) iter.next();
701             if ( table.isPhysicalTable() ) {
702                 
703                 if( !dialect.supportsUniqueConstraintInCreateAlterTable() ) {
704                     Iterator JavaDoc subIter = table.getUniqueKeyIterator();
705                     while ( subIter.hasNext() ) {
706                         UniqueKey uk = (UniqueKey) subIter.next();
707                         script.add( uk.sqlCreateString(dialect, mapping, defaultCatalog, defaultSchema ) );
708                     }
709                 }
710                 
711                 
712                 Iterator JavaDoc subIter = table.getIndexIterator();
713                 while ( subIter.hasNext() ) {
714                     Index index = ( Index ) subIter.next();
715                     script.add( index.sqlCreateString( dialect,
716                             mapping,
717                             defaultCatalog,
718                             defaultSchema ) );
719                 }
720
721                 if ( dialect.hasAlterTable() ) {
722                     subIter = table.getForeignKeyIterator();
723                     while ( subIter.hasNext() ) {
724                         ForeignKey fk = ( ForeignKey ) subIter.next();
725                         if ( fk.isPhysicalConstraint() ) {
726                             script.add( fk.sqlCreateString( dialect, mapping,
727                                 defaultCatalog,
728                                 defaultSchema ) );
729                         }
730                     }
731                 }
732
733             }
734         }
735
736         iter = iterateGenerators( dialect );
737         while ( iter.hasNext() ) {
738             String JavaDoc[] lines = ( ( PersistentIdentifierGenerator ) iter.next() ).sqlCreateStrings( dialect );
739             for ( int i = 0; i < lines.length; i++ ) script.add( lines[i] );
740         }
741
742         return ArrayHelper.toStringArray( script );
743     }
744
745     /**
746      * Generate DDL for altering tables
747      *
748      * @see org.hibernate.tool.hbm2ddl.SchemaUpdate
749      */

750     public String JavaDoc[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata)
751     throws HibernateException {
752         secondPassCompile();
753
754         String JavaDoc defaultCatalog = properties.getProperty(Environment.DEFAULT_CATALOG);
755         String JavaDoc defaultSchema = properties.getProperty(Environment.DEFAULT_SCHEMA);
756
757         ArrayList JavaDoc script = new ArrayList JavaDoc( 50 );
758
759         Iterator JavaDoc iter = getTableMappings();
760         while ( iter.hasNext() ) {
761             Table table = ( Table ) iter.next();
762             if ( table.isPhysicalTable() ) {
763
764                 TableMetadata tableInfo = databaseMetadata.getTableMetadata(
765                         table.getName(),
766                         table.getSchema(),
767                         table.getCatalog()
768                     );
769                 if ( tableInfo == null ) {
770                     script.add( table.sqlCreateString(
771                             dialect,
772                             mapping,
773                             defaultCatalog,
774                             defaultSchema ) );
775                 }
776                 else {
777                     Iterator JavaDoc subiter = table.sqlAlterStrings(
778                             dialect,
779                             mapping,
780                             tableInfo,
781                             defaultCatalog,
782                             defaultSchema
783                         );
784                     while ( subiter.hasNext() ) script.add( subiter.next() );
785                 }
786
787                 Iterator JavaDoc comments = table.sqlCommentStrings(dialect, defaultCatalog, defaultSchema);
788                 while ( comments.hasNext() ) {
789                     script.add( comments.next() );
790                 }
791                 
792             }
793         }
794
795         iter = getTableMappings();
796         while ( iter.hasNext() ) {
797             Table table = ( Table ) iter.next();
798             if ( table.isPhysicalTable() ) {
799
800                 TableMetadata tableInfo = databaseMetadata.getTableMetadata( table.getName(),
801                         table.getSchema(),
802                         table.getCatalog() );
803
804                 if ( dialect.hasAlterTable() ) {
805                     Iterator JavaDoc subIter = table.getForeignKeyIterator();
806                     while ( subIter.hasNext() ) {
807                         ForeignKey fk = ( ForeignKey ) subIter.next();
808                         if ( fk.isPhysicalConstraint() ) {
809                             boolean create = tableInfo == null || (
810                                     tableInfo.getForeignKeyMetadata( fk.getName() ) == null && (
811                                     //Icky workaround for MySQL bug:
812
!( dialect instanceof MySQLDialect ) ||
813                                             tableInfo.getIndexMetadata( fk.getName() ) == null
814                                         )
815                                 );
816                             if ( create ) script.add( fk.sqlCreateString(
817                                     dialect,
818                                     mapping,
819                                     defaultCatalog,
820                                     defaultSchema ) );
821                         }
822                     }
823                 }
824
825             }
826
827             /*//broken, 'cos we don't generate these with names in SchemaExport
828             subIter = table.getIndexIterator();
829             while ( subIter.hasNext() ) {
830                 Index index = (Index) subIter.next();
831                 if ( !index.isForeignKey() || !dialect.hasImplicitIndexForForeignKey() ) {
832                     if ( tableInfo==null || tableInfo.getIndexMetadata( index.getFilterName() ) == null ) {
833                         script.add( index.sqlCreateString(dialect, mapping) );
834                     }
835                 }
836             }
837             //broken, 'cos we don't generate these with names in SchemaExport
838             subIter = table.getUniqueKeyIterator();
839             while ( subIter.hasNext() ) {
840                 UniqueKey uk = (UniqueKey) subIter.next();
841                 if ( tableInfo==null || tableInfo.getIndexMetadata( uk.getFilterName() ) == null ) {
842                     script.add( uk.sqlCreateString(dialect, mapping) );
843                 }
844             }*/

845         }
846
847         iter = iterateGenerators( dialect );
848         while ( iter.hasNext() ) {
849             PersistentIdentifierGenerator generator = ( PersistentIdentifierGenerator ) iter.next();
850             Object JavaDoc key = generator.generatorKey();
851             if ( !databaseMetadata.isSequence( key ) && !databaseMetadata.isTable( key ) ) {
852                 String JavaDoc[] lines = generator.sqlCreateStrings( dialect );
853                 for ( int i = 0; i < lines.length; i++ ) script.add( lines[i] );
854             }
855         }
856
857         return ArrayHelper.toStringArray( script );
858     }
859
860     private void validate() throws MappingException {
861         Iterator JavaDoc iter = classes.values().iterator();
862         while ( iter.hasNext() ) {
863             ( ( PersistentClass ) iter.next() ).validate( mapping );
864         }
865         iter = collections.values().iterator();
866         while ( iter.hasNext() ) {
867             ( ( Collection ) iter.next() ).validate( mapping );
868         }
869     }
870
871     /**
872      * Call this to ensure the mappings are fully compiled/built. Usefull to ensure getting
873      * access to all information in the metamodel when calling e.g. getClassMappings().
874      */

875     public void buildMappings() {
876         secondPassCompile();
877     }
878
879     /**
880      * Find the first possible element in the queue of extends.
881      */

882     protected org.dom4j.Document findPossibleExtends() {
883         Iterator JavaDoc iter = extendsQueue.entrySet().iterator();
884         while ( iter.hasNext() ) {
885             Map.Entry JavaDoc entry = ( Entry ) iter.next();
886             String JavaDoc superclass = ( String JavaDoc ) entry.getKey();
887             if ( getClassMapping( superclass ) != null ) {
888                 List JavaDoc queue = (List JavaDoc) entry.getValue();
889                 if ( queue.isEmpty() ) {
890                     iter.remove();
891                 }
892                 else {
893                     return ( org.dom4j.Document ) queue.remove(0);
894                 }
895             }
896         }
897         return null;
898     }
899
900     // This method may be called many times!!
901
protected void secondPassCompile() throws MappingException {
902         log.info( "processing extends queue" );
903
904         processExtendsQueue();
905
906         log.info( "processing collection mappings" );
907
908         Iterator JavaDoc iter = secondPasses.iterator();
909         while ( iter.hasNext() ) {
910             HbmBinder.SecondPass sp = ( HbmBinder.SecondPass ) iter.next();
911             sp.doSecondPass( classes, CollectionHelper.EMPTY_MAP ); // TODO: align meta-attributes with normal bind...
912
iter.remove();
913         }
914
915         log.info( "processing association property references" );
916
917         iter = propertyReferences.iterator();
918         while ( iter.hasNext() ) {
919             Mappings.PropertyReference upr = ( Mappings.PropertyReference ) iter.next();
920             
921             PersistentClass clazz = getClassMapping( upr.referencedClass );
922             if ( clazz == null ) {
923                 throw new MappingException(
924                         "property-ref to unmapped class: " +
925                         upr.referencedClass
926                     );
927             }
928             
929             Property prop = clazz.getReferencedProperty(upr.propertyName);
930             if ( upr.unique ) {
931                 ( ( SimpleValue ) prop.getValue() ).setAlternateUniqueKey( true );
932             }
933         }
934
935         //TODO: Somehow add the newly created foreign keys to the internal collection
936

937         log.info( "processing foreign key constraints" );
938
939         iter = getTableMappings();
940         Set JavaDoc done = new HashSet JavaDoc();
941         while ( iter.hasNext() ) {
942             secondPassCompileForeignKeys( ( Table ) iter.next(), done );
943         }
944
945     }
946
947     /**
948      * Try to empty the extends queue.
949      */

950     private void processExtendsQueue() {
951         org.dom4j.Document document = findPossibleExtends();
952         while ( document != null ) {
953             add( document );
954             document = findPossibleExtends();
955         }
956
957         if ( extendsQueue.size() > 0 ) {
958             Iterator JavaDoc iterator = extendsQueue.keySet().iterator();
959             StringBuffer JavaDoc buf = new StringBuffer JavaDoc( "Following superclasses referenced in extends not found: " );
960             while ( iterator.hasNext() ) {
961                 String JavaDoc element = ( String JavaDoc ) iterator.next();
962                 buf.append( element );
963                 if ( iterator.hasNext() ) buf.append( "," );
964             }
965             throw new MappingException( buf.toString() );
966         }
967     }
968
969     protected void secondPassCompileForeignKeys(Table table, Set JavaDoc done) throws MappingException {
970
971         table.createForeignKeys();
972
973         Iterator JavaDoc iter = table.getForeignKeyIterator();
974         while ( iter.hasNext() ) {
975
976             ForeignKey fk = ( ForeignKey ) iter.next();
977             if ( !done.contains( fk ) ) {
978                 done.add( fk );
979                 final String JavaDoc referencedEntityName = fk.getReferencedEntityName();
980                 if (referencedEntityName==null) {
981                     throw new MappingException(
982                             "An association from the table "+
983                             fk.getTable().getName() +
984                             " does not specify the referenced entity"
985                         );
986                 }
987                 if ( log.isDebugEnabled() ) {
988                     log.debug( "resolving reference to class: " + referencedEntityName );
989                 }
990                 PersistentClass referencedClass = ( PersistentClass ) classes.get( referencedEntityName );
991                 if ( referencedClass == null ) {
992                     throw new MappingException(
993                             "An association from the table " +
994                             fk.getTable().getName() +
995                             " refers to an unmapped class: " +
996                             referencedEntityName
997                         );
998                 }
999                 if ( referencedClass.isJoinedSubclass() ) {
1000                    secondPassCompileForeignKeys( referencedClass.getSuperclass().getTable(), done );
1001                }
1002                fk.setReferencedTable( referencedClass.getTable() );
1003                fk.alignColumns();
1004            }
1005        }
1006    }
1007
1008    /**
1009     * Get the named queries
1010     */

1011    public Map JavaDoc getNamedQueries() {
1012        return namedQueries;
1013    }
1014
1015    /**
1016     * Instantiate a new <tt>SessionFactory</tt>, using the properties and
1017     * mappings in this configuration. The <tt>SessionFactory</tt> will be
1018     * immutable, so changes made to the <tt>Configuration</tt> after
1019     * building the <tt>SessionFactory</tt> will not affect it.
1020     *
1021     * @return a new factory for <tt>Session</tt>s
1022     * @see org.hibernate.SessionFactory
1023     */

1024    public SessionFactory buildSessionFactory() throws HibernateException {
1025        log.debug( "Preparing to build session factory with filters : " + filterDefinitions );
1026        secondPassCompile();
1027        validate();
1028        Environment.verifyProperties( properties );
1029        Properties JavaDoc copy = new Properties JavaDoc();
1030        copy.putAll( properties );
1031        Settings settings = buildSettings();
1032        
1033        return new SessionFactoryImpl(
1034                this,
1035                mapping,
1036                settings,
1037                sessionEventListenerConfig.shallowCopy()
1038            );
1039    }
1040
1041    /**
1042     * Return the configured <tt>Interceptor</tt>
1043     */

1044    public Interceptor getInterceptor() {
1045        return interceptor;
1046    }
1047
1048    /**
1049     * Get all properties
1050     */

1051    public Properties JavaDoc getProperties() {
1052        return properties;
1053    }
1054
1055    /**
1056     * Configure an <tt>Interceptor</tt>
1057     */

1058    public Configuration setInterceptor(Interceptor interceptor) {
1059        this.interceptor = interceptor;
1060        return this;
1061    }
1062
1063    /**
1064     * Specify a completely new set of properties
1065     */

1066    public Configuration setProperties(Properties JavaDoc properties) {
1067        this.properties = properties;
1068        return this;
1069    }
1070
1071    /**
1072     * Set the given properties
1073     */

1074    public Configuration addProperties(Properties JavaDoc extraProperties) {
1075        this.properties.putAll( extraProperties );
1076        return this;
1077    }
1078
1079    /**
1080     * Set a property
1081     */

1082    public Configuration setProperty(String JavaDoc propertyName, String JavaDoc value) {
1083        properties.setProperty( propertyName, value );
1084        return this;
1085    }
1086
1087    /**
1088     * Get a property
1089     */

1090    public String JavaDoc getProperty(String JavaDoc propertyName) {
1091        return properties.getProperty( propertyName );
1092    }
1093
1094    private void addProperties(Element parent) {
1095        Iterator JavaDoc iter = parent.elementIterator( "property" );
1096        while ( iter.hasNext() ) {
1097            Element node = ( Element ) iter.next();
1098            String JavaDoc name = node.attributeValue( "name" );
1099            String JavaDoc value = node.getText().trim();
1100            log.debug( name + "=" + value );
1101            properties.setProperty( name, value );
1102            if ( !name.startsWith( "hibernate" ) ) {
1103                properties.setProperty( "hibernate." + name, value );
1104            }
1105        }
1106        Environment.verifyProperties( properties );
1107    }
1108
1109    /**
1110     * Get the configuration file as an <tt>InputStream</tt>. Might be overridden
1111     * by subclasses to allow the configuration to be located by some arbitrary
1112     * mechanism.
1113     */

1114    protected InputStream JavaDoc getConfigurationInputStream(String JavaDoc resource) throws HibernateException {
1115
1116        log.info( "Configuration resource: " + resource );
1117
1118        InputStream JavaDoc stream = Environment.class.getResourceAsStream( resource );
1119        if ( stream == null ) {
1120            stream = Thread.currentThread().getContextClassLoader()
1121                    .getResourceAsStream( resource );
1122        }
1123        if ( stream == null ) {
1124            log.warn( resource + " not found" );
1125            throw new HibernateException( resource + " not found" );
1126        }
1127        return stream;
1128
1129    }
1130
1131    /**
1132     * Use the mappings and properties specified in an application
1133     * resource named <tt>hibernate.cfg.xml</tt>.
1134     */

1135    public Configuration configure() throws HibernateException {
1136        configure( "/hibernate.cfg.xml" );
1137        return this;
1138    }
1139
1140    /**
1141     * Use the mappings and properties specified in the given application
1142     * resource. The format of the resource is defined in
1143     * <tt>hibernate-configuration-3.0.dtd</tt>.
1144     * <p/>
1145     * The resource is found via <tt>getConfigurationInputStream(resource)</tt>.
1146     */

1147    public Configuration configure(String JavaDoc resource) throws HibernateException {
1148        log.info( "configuring from resource: " + resource );
1149        InputStream JavaDoc stream = getConfigurationInputStream( resource );
1150        return doConfigure( stream, resource );
1151    }
1152
1153    /**
1154     * Use the mappings and properties specified in the given document.
1155     * The format of the document is defined in
1156     * <tt>hibernate-configuration-2.2.dtd</tt>.
1157     *
1158     * @param url URL from which you wish to load the configuration
1159     * @return A configuration configured via the file
1160     * @throws HibernateException
1161     */

1162    public Configuration configure(URL JavaDoc url) throws HibernateException {
1163        log.info( "configuring from url: " + url.toString() );
1164        try {
1165            return doConfigure( url.openStream(), url.toString() );
1166        }
1167        catch ( IOException JavaDoc ioe ) {
1168            throw new HibernateException( "could not configure from URL: " + url, ioe );
1169        }
1170    }
1171
1172    /**
1173     * Use the mappings and properties specified in the given application
1174     * file. The format of the file is defined in
1175     * <tt>hibernate-configuration-3.0.dtd</tt>.
1176     *
1177     * @param configFile <tt>File</tt> from which you wish to load the configuration
1178     * @return A configuration configured via the file
1179     * @throws HibernateException
1180     */

1181    public Configuration configure(File JavaDoc configFile) throws HibernateException {
1182        log.info( "configuring from file: " + configFile.getName() );
1183        try {
1184            return doConfigure( new FileInputStream JavaDoc( configFile ), configFile.toString() );
1185        }
1186        catch ( FileNotFoundException JavaDoc fnfe ) {
1187            throw new HibernateException( "could not find file: " + configFile, fnfe );
1188        }
1189    }
1190
1191    /**
1192     * Use the mappings and properties specified in the given application
1193     * resource. The format of the resource is defined in
1194     * <tt>hibernate-configuration-2.2.dtd</tt>.
1195     *
1196     * @param stream Inputstream to be read from
1197     * @param resourceName The name to use in warning/error messages
1198     * @return A configuration configured via the stream
1199     * @throws HibernateException
1200     */

1201    protected Configuration doConfigure(InputStream JavaDoc stream, String JavaDoc resourceName) throws HibernateException {
1202
1203        org.dom4j.Document doc;
1204        try {
1205            List JavaDoc errors = new ArrayList JavaDoc();
1206            doc = xmlHelper.createSAXReader( resourceName, errors, entityResolver )
1207                    .read( new InputSource JavaDoc( stream ) );
1208            if ( errors.size() != 0 ) {
1209                throw new MappingException(
1210                        "invalid configuration",
1211                        ( Throwable JavaDoc ) errors.get( 0 )
1212                    );
1213            }
1214        }
1215        catch ( DocumentException e ) {
1216            throw new HibernateException(
1217                    "Could not parse configuration: " + resourceName,
1218                    e
1219                );
1220        }
1221        finally {
1222            try {
1223                stream.close();
1224            }
1225            catch ( IOException JavaDoc ioe ) {
1226                log.warn( "could not close input stream for: " + resourceName, ioe );
1227            }
1228        }
1229
1230        return doConfigure( doc );
1231
1232    }
1233
1234    /**
1235     * Use the mappings and properties specified in the given XML document.
1236     * The format of the file is defined in
1237     * <tt>hibernate-configuration-2.2.dtd</tt>.
1238     *
1239     * @param document an XML document from which you wish to load the configuration
1240     * @return A configuration configured via the <tt>Document</tt>
1241     * @throws HibernateException if there is problem in accessing the file.
1242     */

1243    public Configuration configure(Document JavaDoc document) throws HibernateException {
1244        log.info( "configuring from XML document" );
1245        return doConfigure( xmlHelper.createDOMReader().read( document ) );
1246    }
1247
1248    protected Configuration doConfigure(org.dom4j.Document doc) throws HibernateException {
1249
1250        Element sfNode = doc.getRootElement().element( "session-factory" );
1251        String JavaDoc name = sfNode.attributeValue( "name" );
1252        if ( name != null ) properties.setProperty( Environment.SESSION_FACTORY_NAME, name );
1253        addProperties( sfNode );
1254        parseSessionFactory( sfNode, name );
1255
1256        Element secNode = doc.getRootElement().element( "security" );
1257        if ( secNode != null ) parseSecurity( secNode );
1258
1259        log.info( "Configured SessionFactory: " + name );
1260        log.debug( "properties: " + properties );
1261
1262        return this;
1263
1264    }
1265
1266    private void parseSessionFactory(Element sfNode, String JavaDoc name) {
1267        Iterator JavaDoc elements = sfNode.elementIterator();
1268        while ( elements.hasNext() ) {
1269            Element subelement = ( Element ) elements.next();
1270            String JavaDoc subelementName = subelement.getName();
1271            if ( "mapping".equals( subelementName ) ) {
1272                parseMappingElement(subelement, name);
1273            }
1274            else if ( "class-cache".equals( subelementName ) ) {
1275                String JavaDoc className = subelement.attributeValue( "class" );
1276                Attribute regionNode = subelement.attribute( "region" );
1277                final String JavaDoc region = ( regionNode == null ) ? className : regionNode.getValue();
1278                setCacheConcurrencyStrategy( className, subelement.attributeValue( "usage" ), region );
1279            }
1280            else if ( "collection-cache".equals( subelementName ) ) {
1281                String JavaDoc role = subelement.attributeValue( "collection" );
1282                Attribute regionNode = subelement.attribute( "region" );
1283                final String JavaDoc region = ( regionNode == null ) ? role : regionNode.getValue();
1284                setCollectionCacheConcurrencyStrategy( role, subelement.attributeValue( "usage" ), region );
1285            }
1286            else if ( "listener".equals( subelementName ) ) {
1287                parseListener( subelement );
1288            }
1289        }
1290    }
1291
1292    protected void parseMappingElement(Element subelement, String JavaDoc name) {
1293        Attribute rsrc = subelement.attribute( "resource" );
1294        Attribute file = subelement.attribute( "file" );
1295        Attribute jar = subelement.attribute( "jar" );
1296        Attribute pkg = subelement.attribute( "package" );
1297        Attribute clazz = subelement.attribute( "class" );
1298        if ( rsrc != null ) {
1299            log.debug( name + "<-" + rsrc );
1300            addResource( rsrc.getValue() );
1301        }
1302        else if ( jar != null ) {
1303            log.debug( name + "<-" + jar );
1304            addJar( new File JavaDoc( jar.getValue() ) );
1305        }
1306        else if ( pkg != null ) {
1307            throw new MappingException("An AnnotationConfiguration instance is required to use <mapping package=\"" + pkg.getValue() + "\"/>");
1308        }
1309        else if ( clazz != null ) {
1310            throw new MappingException("An AnnotationConfiguration instance is required to use <mapping clazz=\"" + clazz.getValue() + "\"/>");
1311        }
1312        else {
1313            if ( file == null ) throw new MappingException( "<mapping> element in configuration specifies no attributes" );
1314            log.debug( name + "<-" + file );
1315            addFile( file.getValue() );
1316        }
1317    }
1318
1319    private void parseSecurity(Element secNode) {
1320        String JavaDoc contextId = secNode.attributeValue( "context" );
1321        log.info( "JACC contextID: " + contextId );
1322        JACCConfiguration jcfg = new JACCConfiguration( contextId );
1323        Iterator JavaDoc grantElements = secNode.elementIterator();
1324        while ( grantElements.hasNext() ) {
1325            Element grantElement = ( Element ) grantElements.next();
1326            String JavaDoc elementName = grantElement.getName();
1327            if ( "grant".equals( elementName ) ) {
1328                jcfg.addPermission(
1329                        grantElement.attributeValue( "role" ),
1330                        grantElement.attributeValue( "entity-name" ),
1331                        grantElement.attributeValue( "actions" )
1332                    );
1333            }
1334        }
1335    }
1336
1337    private void parseListener(Element element) {
1338        String JavaDoc type = element.attributeValue( "type" );
1339        String JavaDoc impl = element.attributeValue( "class" );
1340        log.debug( "Encountered configured listener : " + type + "=" + impl );
1341        setListener( type, impl );
1342    }
1343
1344    public void setListener(String JavaDoc type, String JavaDoc listenerClass) {
1345        try {
1346            Object JavaDoc listener = ReflectHelper.classForName( listenerClass ).newInstance();
1347            setListener( type, listener );
1348        }
1349        catch ( Throwable JavaDoc t ) {
1350            log.warn( "Unable to instantiate specified listener class [" + listenerClass + "]", t );
1351        }
1352    }
1353
1354    public void setListener(String JavaDoc type, Object JavaDoc listener) {
1355        if ( "auto-flush".equals( type ) ) {
1356            sessionEventListenerConfig.setAutoFlushEventListener( ( AutoFlushEventListener ) listener );
1357        }
1358        else if ( "merge".equals( type ) ) {
1359            sessionEventListenerConfig.setMergeEventListener( ( MergeEventListener ) listener );
1360        }
1361        else if ( "create".equals( type ) ) {
1362            sessionEventListenerConfig.setCreateEventListener( ( PersistEventListener ) listener );
1363        }
1364        else if ( "delete".equals( type ) ) {
1365            sessionEventListenerConfig.setDeleteEventListener( ( DeleteEventListener ) listener );
1366        }
1367        else if ( "dirty-check".equals( type ) ) {
1368            sessionEventListenerConfig.setDirtyCheckEventListener( ( DirtyCheckEventListener ) listener );
1369        }
1370        else if ( "evict".equals( type ) ) {
1371            sessionEventListenerConfig.setEvictEventListener( ( EvictEventListener ) listener );
1372        }
1373        else if ( "flush".equals( type ) ) {
1374            sessionEventListenerConfig.setFlushEventListener( ( FlushEventListener ) listener );
1375        }
1376        else if ( "flush-entity".equals( type ) ) {
1377            sessionEventListenerConfig.setFlushEntityEventListener( ( FlushEntityEventListener ) listener );
1378        }
1379        else if ( "load".equals( type ) ) {
1380            sessionEventListenerConfig.setLoadEventListener( ( LoadEventListener ) listener );
1381        }
1382        else if ( "load-collection".equals( type ) ) {
1383            sessionEventListenerConfig.setInitializeCollectionEventListener( ( InitializeCollectionEventListener ) listener );
1384        }
1385        else if ( "lock".equals( type ) ) {
1386            sessionEventListenerConfig.setLockEventListener( ( LockEventListener ) listener );
1387        }
1388        else if ( "refresh".equals( type ) ) {
1389            sessionEventListenerConfig.setRefreshEventListener( ( RefreshEventListener ) listener );
1390        }
1391        else if ( "replicate".equals( type ) ) {
1392            sessionEventListenerConfig.setReplicateEventListener( ( ReplicateEventListener ) listener );
1393        }
1394        else if ( "save-update".equals( type ) ) {
1395            sessionEventListenerConfig.setSaveOrUpdateEventListener( ( SaveOrUpdateEventListener ) listener );
1396        }
1397        else if ( "save".equals( type ) ) {
1398            sessionEventListenerConfig.setSaveEventListener( ( SaveOrUpdateEventListener ) listener );
1399        }
1400        else if ( "update".equals( type ) ) {
1401            sessionEventListenerConfig.setUpdateEventListener( ( SaveOrUpdateEventListener ) listener );
1402        }
1403        else if ( "pre-load".equals( type ) ) {
1404            sessionEventListenerConfig.setPreLoadEventListener( ( PreLoadEventListener ) listener );
1405        }
1406        else if ( "pre-update".equals( type ) ) {
1407            sessionEventListenerConfig.setPreUpdateEventListener( ( PreUpdateEventListener ) listener );
1408        }
1409        else if ( "pre-delete".equals( type ) ) {
1410            sessionEventListenerConfig.setPreDeleteEventListener( ( PreDeleteEventListener ) listener );
1411        }
1412        else if ( "pre-insert".equals( type ) ) {
1413            sessionEventListenerConfig.setPreInsertEventListener( ( PreInsertEventListener ) listener );
1414        }
1415        else if ( "post-load".equals( type ) ) {
1416            sessionEventListenerConfig.setPostLoadEventListener( ( PostLoadEventListener ) listener );
1417        }
1418        else if ( "post-update".equals( type ) ) {
1419            sessionEventListenerConfig.setPostUpdateEventListener( ( PostUpdateEventListener ) listener );
1420        }
1421        else if ( "post-delete".equals( type ) ) {
1422            sessionEventListenerConfig.setPostDeleteEventListener( ( PostDeleteEventListener ) listener );
1423        }
1424        else if ( "post-insert".equals( type ) ) {
1425            sessionEventListenerConfig.setPostInsertEventListener( ( PostInsertEventListener ) listener );
1426        }
1427        else {
1428            log.warn( "Unrecognized listener type [" + type + "]" );
1429        }
1430    }
1431
1432    public SessionEventListenerConfig getSessionEventListenerConfig() {
1433        return sessionEventListenerConfig;
1434    }
1435
1436    RootClass getRootClassMapping(String JavaDoc clazz) throws MappingException {
1437        try {
1438            return ( RootClass ) getClassMapping( clazz );
1439        }
1440        catch ( ClassCastException JavaDoc cce ) {
1441            throw new MappingException( "You may only specify a cache for root <class> mappings" );
1442        }
1443    }
1444
1445    /**
1446     * Set up a cache for an entity class
1447     *
1448     * @param clazz
1449     * @param concurrencyStrategy
1450     * @return Configuration
1451     * @throws MappingException
1452     */

1453    public Configuration setCacheConcurrencyStrategy(String JavaDoc clazz, String JavaDoc concurrencyStrategy)
1454            throws MappingException {
1455        setCacheConcurrencyStrategy( clazz, concurrencyStrategy, clazz );
1456        return this;
1457    }
1458
1459    void setCacheConcurrencyStrategy(String JavaDoc clazz, String JavaDoc concurrencyStrategy, String JavaDoc region)
1460            throws MappingException {
1461        RootClass rootClass = getRootClassMapping( clazz );
1462        if (rootClass == null) throw new MappingException("Cannot cache an unknown entity: " + clazz);
1463        rootClass.setCacheConcurrencyStrategy( concurrencyStrategy );
1464        rootClass.setCacheRegionName( region );
1465    }
1466
1467    /**
1468     * Set up a cache for a collection role
1469     *
1470     * @param collectionRole
1471     * @param concurrencyStrategy
1472     * @return Configuration
1473     * @throws MappingException
1474     */

1475    public Configuration setCollectionCacheConcurrencyStrategy(String JavaDoc collectionRole, String JavaDoc concurrencyStrategy)
1476            throws MappingException {
1477        setCollectionCacheConcurrencyStrategy( collectionRole, concurrencyStrategy, collectionRole );
1478        return this;
1479    }
1480
1481    void setCollectionCacheConcurrencyStrategy(String JavaDoc collectionRole, String JavaDoc concurrencyStrategy, String JavaDoc region)
1482            throws MappingException {
1483        Collection collection = getCollectionMapping( collectionRole );
1484        if (collection == null) throw new MappingException("Cannot cache an unknown collection: " + collectionRole);
1485        collection.setCacheConcurrencyStrategy( concurrencyStrategy );
1486        collection.setCacheRegionName( region );
1487    }
1488
1489    /**
1490     * Get the query language imports
1491     *
1492     * @return a mapping from "import" names to fully qualified class names
1493     */

1494    public Map JavaDoc getImports() {
1495        return imports;
1496    }
1497
1498    /**
1499     * Create an object-oriented view of the configuration properties
1500     */

1501    public Settings buildSettings() throws HibernateException {
1502        return settingsFactory.buildSettings( properties );
1503    }
1504
1505    public Map JavaDoc getNamedSQLQueries() {
1506        return namedSqlQueries;
1507    }
1508
1509    public Map JavaDoc getSqlResultSetMappings() {
1510        return sqlResultSetMappings;
1511    }
1512
1513    /**
1514     * @return the NamingStrategy.
1515     */

1516    public NamingStrategy getNamingStrategy() {
1517        return namingStrategy;
1518    }
1519
1520    /**
1521     * Set a custom naming strategy
1522     *
1523     * @param namingStrategy the NamingStrategy to set
1524     */

1525    public Configuration setNamingStrategy(NamingStrategy namingStrategy) {
1526        this.namingStrategy = namingStrategy;
1527        return this;
1528    }
1529
1530    private Mapping buildMapping() {
1531        return new Mapping() {
1532            /**
1533             * Returns the identifier type of a mapped class
1534             */

1535            public Type getIdentifierType(String JavaDoc persistentClass) throws MappingException {
1536                PersistentClass pc = ( ( PersistentClass ) classes.get( persistentClass ) );
1537                if (pc==null) throw new MappingException("persistent class not known: " + persistentClass);
1538                return pc.getIdentifier().getType();
1539            }
1540
1541            public String JavaDoc getIdentifierPropertyName(String JavaDoc persistentClass) throws MappingException {
1542                final PersistentClass pc = ( PersistentClass ) classes.get( persistentClass );
1543                if (pc==null) throw new MappingException("persistent class not known: " + persistentClass);
1544                if ( !pc.hasIdentifierProperty() ) return null;
1545                return pc.getIdentifierProperty().getName();
1546            }
1547
1548            public Type getReferencedPropertyType(String JavaDoc persistentClass, String JavaDoc propertyName) throws MappingException {
1549                final PersistentClass pc = ( PersistentClass ) classes.get( persistentClass );
1550                if (pc==null) throw new MappingException("persistent class not known: " + persistentClass);
1551                Property prop = pc.getReferencedProperty(propertyName);
1552                if (prop==null) throw new MappingException("property not known: " + persistentClass + '.' + propertyName);
1553                return prop.getType();
1554            }
1555        };
1556    }
1557    
1558    private void readObject(ObjectInputStream JavaDoc ois) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
1559        ois.defaultReadObject();
1560        this.mapping = buildMapping();
1561        xmlHelper = new XMLHelper();
1562    }
1563
1564    public Map JavaDoc getFilterDefinitions() {
1565        return filterDefinitions;
1566    }
1567
1568    public void addFilterDefinition(FilterDefinition definition) {
1569        filterDefinitions.put( definition.getFilterName(), definition );
1570    }
1571}
1572
1573
1574
1575
1576
1577
1578
Popular Tags