KickJava   Java API By Example, From Geeks To Geeks.

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


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.AmberRuntimeException;
33 import com.caucho.amber.cfg.EntityConfig;
34 import com.caucho.amber.cfg.EntityMappingsConfig;
35 import com.caucho.amber.cfg.PersistenceConfig;
36 import com.caucho.amber.cfg.PersistenceUnitConfig;
37 import com.caucho.amber.gen.AmberEnhancer;
38 import com.caucho.amber.gen.AmberGenerator;
39 import com.caucho.amber.type.EmbeddableType;
40 import com.caucho.amber.type.EntityType;
41 import com.caucho.amber.type.ListenerType;
42 import com.caucho.bytecode.JClass;
43 import com.caucho.bytecode.JClassLoader;
44 import com.caucho.config.Config;
45 import com.caucho.config.ConfigException;
46 import com.caucho.loader.DynamicClassLoader;
47 import com.caucho.loader.Environment;
48 import com.caucho.loader.EnvironmentLocal;
49 import com.caucho.loader.enhancer.EnhancerManager;
50 import com.caucho.vfs.Path;
51
52 import javax.sql.DataSource JavaDoc;
53 import java.io.InputStream JavaDoc;
54 import java.util.ArrayList JavaDoc;
55 import java.util.HashMap JavaDoc;
56 import java.util.Iterator JavaDoc;
57 import java.util.Map JavaDoc;
58 import java.util.logging.Level JavaDoc;
59 import java.util.logging.Logger JavaDoc;
60
61 /**
62  * Environment-based container.
63  */

64 public class AmberContainer {
65   private static final Logger JavaDoc log
66     = Logger.getLogger(AmberContainer.class.getName());
67
68   private static final EnvironmentLocal<AmberContainer> _localContainer
69     = new EnvironmentLocal<AmberContainer>();
70
71   private ClassLoader JavaDoc _parentLoader;
72   // private EnhancingClassLoader _enhancedLoader;
73

74   private JClassLoader _jClassLoader;
75
76   private AmberEnhancer _enhancer;
77
78   private DataSource JavaDoc _dataSource;
79   private DataSource JavaDoc _readDataSource;
80   private DataSource JavaDoc _xaDataSource;
81
82   private boolean _createDatabaseTables;
83
84   private HashMap JavaDoc<String JavaDoc,AmberPersistenceUnit> _unitMap
85     = new HashMap JavaDoc<String JavaDoc,AmberPersistenceUnit>();
86
87   private HashMap JavaDoc<String JavaDoc,EmbeddableType> _embeddableMap
88     = new HashMap JavaDoc<String JavaDoc,EmbeddableType>();
89
90   private HashMap JavaDoc<String JavaDoc,EntityType> _entityMap
91     = new HashMap JavaDoc<String JavaDoc,EntityType>();
92
93   private HashMap JavaDoc<String JavaDoc,ListenerType> _defaultListenerMap
94     = new HashMap JavaDoc<String JavaDoc,ListenerType>();
95
96   private HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<ListenerType>>
97     _entityListenerMap = new HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<ListenerType>>();
98
99   private Throwable JavaDoc _exception;
100
101   private HashMap JavaDoc<String JavaDoc,Throwable JavaDoc> _embeddableExceptionMap
102     = new HashMap JavaDoc<String JavaDoc,Throwable JavaDoc>();
103
104   private HashMap JavaDoc<String JavaDoc,Throwable JavaDoc> _entityExceptionMap
105     = new HashMap JavaDoc<String JavaDoc,Throwable JavaDoc>();
106
107   private HashMap JavaDoc<String JavaDoc,Throwable JavaDoc> _listenerExceptionMap
108     = new HashMap JavaDoc<String JavaDoc,Throwable JavaDoc>();
109
110   private AmberContainer()
111   {
112     _parentLoader = Thread.currentThread().getContextClassLoader();
113     _jClassLoader = EnhancerManager.create(_parentLoader).getJavaClassLoader();
114
115     _enhancer = new AmberEnhancer(this);
116
117     EnhancerManager.create().addClassEnhancer(_enhancer);
118
119     try {
120       if (_parentLoader instanceof DynamicClassLoader)
121         ((DynamicClassLoader) _parentLoader).make();
122     } catch (RuntimeException JavaDoc e) {
123       throw e;
124     } catch (Exception JavaDoc e) {
125       throw new RuntimeException JavaDoc(e);
126     }
127   }
128
129   /**
130    * Returns the local container.
131    */

132   public static AmberContainer getLocalContainer()
133   {
134     synchronized (_localContainer) {
135       AmberContainer container = _localContainer.getLevel();
136
137       if (container == null) {
138         container = new AmberContainer();
139
140         _localContainer.set(container);
141       }
142
143       return container;
144     }
145   }
146
147   /**
148    * Sets the primary data source.
149    */

150   public void setDataSource(DataSource JavaDoc dataSource)
151   {
152     _dataSource = dataSource;
153   }
154
155   /**
156    * Gets the primary data source.
157    */

158   public DataSource JavaDoc getDataSource()
159   {
160     return _dataSource;
161   }
162
163   /**
164    * Sets the read data source.
165    */

166   public void setReadDataSource(DataSource JavaDoc dataSource)
167   {
168     _readDataSource = dataSource;
169   }
170
171   /**
172    * Gets the read data source.
173    */

174   public DataSource JavaDoc getReadDataSource()
175   {
176     return _readDataSource;
177   }
178
179   /**
180    * Sets the xa data source.
181    */

182   public void setXADataSource(DataSource JavaDoc dataSource)
183   {
184     _xaDataSource = dataSource;
185   }
186
187   /**
188    * Gets the XA data source.
189    */

190   public DataSource JavaDoc getXADataSource()
191   {
192     return _xaDataSource;
193   }
194
195   /**
196    * True if database tables should be created automatically.
197    */

198   public boolean getCreateDatabaseTables()
199   {
200     return _createDatabaseTables;
201   }
202
203   /**
204    * True if database tables should be created automatically.
205    */

206   public void setCreateDatabaseTables(boolean isCreate)
207   {
208     _createDatabaseTables = isCreate;
209   }
210
211   /**
212    * Returns the parent loader
213    */

214   public ClassLoader JavaDoc getParentClassLoader()
215   {
216     return _parentLoader;
217   }
218
219   /**
220    * Returns the parent loader
221    */

222   public ClassLoader JavaDoc getEnhancedLoader()
223   {
224     return _parentLoader;
225   }
226
227   /**
228    * Returns the enhancer.
229    */

230   public AmberGenerator getGenerator()
231   {
232     return _enhancer;
233   }
234
235   /**
236    * Returns the persistence unit JNDI context.
237    */

238   public String JavaDoc getPersistenceUnitJndiPrefix()
239   {
240     return "java:comp/env/persistence/_amber_PersistenceUnit/";
241   }
242
243   /**
244    * Returns the persistence unit JNDI context.
245    */

246   public String JavaDoc getPersistenceContextJndiPrefix()
247   {
248     //return "java:comp/env/persistence/PersistenceContext/";
249
return "java:comp/env/persistence/";
250   }
251
252   /**
253    * Returns the JClassLoader.
254    */

255   public JClassLoader getJClassLoader()
256   {
257     return _jClassLoader;
258   }
259
260   /**
261    * Returns the EmbeddableType for an introspected class.
262    */

263   public EmbeddableType getEmbeddable(String JavaDoc className)
264   {
265     Throwable JavaDoc e = _embeddableExceptionMap.get(className);
266
267     if (e != null)
268       throw new AmberRuntimeException(e);
269     else if (_exception != null) {
270       throw new AmberRuntimeException(_exception);
271     }
272
273     return _embeddableMap.get(className);
274   }
275
276   /**
277    * Returns the EntityType for an introspected class.
278    */

279   public EntityType getEntity(String JavaDoc className)
280   {
281     Throwable JavaDoc e = _entityExceptionMap.get(className);
282
283     if (e != null)
284       throw new AmberRuntimeException(e);
285     else if (_exception != null) {
286       throw new AmberRuntimeException(_exception);
287     }
288
289     return _entityMap.get(className);
290   }
291
292   /**
293    * Returns the default ListenerType for an introspected class.
294    */

295   public ListenerType getDefaultListener(String JavaDoc className)
296   {
297     Throwable JavaDoc e = _listenerExceptionMap.get(className);
298
299     if (e != null)
300       throw new AmberRuntimeException(e);
301     else if (_exception != null) {
302       throw new AmberRuntimeException(_exception);
303     }
304
305     return _defaultListenerMap.get(className);
306   }
307
308   /**
309    * Returns the entity ListenerType for an introspected class.
310    */

311   public ListenerType getEntityListener(String JavaDoc className)
312   {
313     Throwable JavaDoc e = _listenerExceptionMap.get(className);
314
315     if (e != null)
316       throw new AmberRuntimeException(e);
317     else if (_exception != null) {
318       throw new AmberRuntimeException(_exception);
319     }
320
321     ArrayList JavaDoc<ListenerType> listenerList;
322
323     for (Map.Entry JavaDoc<String JavaDoc, ArrayList JavaDoc<ListenerType>>
324            entry : _entityListenerMap.entrySet()) {
325
326       listenerList = entry.getValue();
327
328       if (listenerList == null)
329         continue;
330
331       for (ListenerType listener : listenerList) {
332         if (className.equals(listener.getBeanClass().getName()))
333           return listener;
334       }
335     }
336
337     return null;
338   }
339
340   /**
341    * Returns the listener for an introspected class.
342    */

343   public ListenerType getListener(String JavaDoc className)
344   {
345     ListenerType listener = getDefaultListener(className);
346
347     if (listener == null)
348       listener = getEntityListener(className);
349
350     return listener;
351   }
352
353   /**
354    * Returns the entity listeners for an entity.
355    */

356   public ArrayList JavaDoc<ListenerType>
357   getEntityListeners(String JavaDoc entityClassName)
358   {
359     return _entityListenerMap.get(entityClassName);
360   }
361
362   /**
363    * Adds an entity for an introspected class.
364    */

365   public void addEntityException(String JavaDoc className, Throwable JavaDoc e)
366   {
367     _entityExceptionMap.put(className, e);
368   }
369
370   /**
371    * Adds an entity for an introspected class.
372    */

373   public void addException(Throwable JavaDoc e)
374   {
375     if (_exception == null) {
376       _exception = e;
377
378       Environment.setConfigException(e);
379     }
380   }
381
382   public Throwable JavaDoc getConfigException()
383   {
384     return _exception;
385   }
386
387   /**
388    * Adds an embeddable for an introspected class.
389    */

390   public void addEmbeddable(String JavaDoc className, EmbeddableType type)
391   {
392     _embeddableMap.put(className, type);
393   }
394
395   /**
396    * Adds an entity for an introspected class.
397    */

398   public void addEntity(String JavaDoc className, EntityType type)
399   {
400     _entityMap.put(className, type);
401   }
402
403   /**
404    * Adds a default listener.
405    */

406   public void addDefaultListener(String JavaDoc className,
407                                  ListenerType type)
408   {
409     _defaultListenerMap.put(className, type);
410   }
411
412   /**
413    * Adds an entity listener.
414    */

415   public void addEntityListener(String JavaDoc entityClassName,
416                                 ListenerType listenerType)
417   {
418     ArrayList JavaDoc<ListenerType> listenerList
419       = _entityListenerMap.get(entityClassName);
420
421     if (listenerList == null) {
422       listenerList = new ArrayList JavaDoc<ListenerType>();
423       _entityListenerMap.put(entityClassName, listenerList);
424     }
425
426     listenerList.add(listenerType);
427   }
428
429   /**
430    * Initialize the entity homes.
431    */

432   public void initEntityHomes()
433   {
434     throw new UnsupportedOperationException JavaDoc();
435   }
436
437   public AmberPersistenceUnit createPersistenceUnit(String JavaDoc name)
438   {
439     AmberPersistenceUnit unit = new AmberPersistenceUnit(this, name);
440
441     _unitMap.put(unit.getName(), unit);
442
443     return unit;
444   }
445
446   public AmberPersistenceUnit getPersistenceUnit(String JavaDoc name)
447   {
448     if (_exception != null)
449       throw new AmberRuntimeException(_exception);
450
451     return _unitMap.get(name);
452   }
453
454   /**
455    * Adds a persistence root.
456    */

457   public void addPersistenceRoot(Path root)
458   {
459     Path persistenceXml = root.lookup("META-INF/persistence.xml");
460     InputStream JavaDoc is = null;
461
462     try {
463
464       Path ormXml = root.lookup("META-INF/orm.xml");
465
466       EntityMappingsConfig entityMappings = null;
467
468       if (ormXml.exists()) {
469         is = ormXml.openRead();
470
471         entityMappings = new EntityMappingsConfig();
472         entityMappings.setRoot(root);
473
474         new Config().configure(entityMappings, is,
475                                "com/caucho/amber/cfg/mapping-30.rnc");
476       }
477
478       HashMap JavaDoc<String JavaDoc, JClass> classMap
479         = new HashMap JavaDoc<String JavaDoc, JClass>();
480
481       // XXX: This is not necessary when <exclude-unlisted-classes/>
482
lookupClasses(root.getPath().length(), root, classMap, entityMappings);
483
484       is = persistenceXml.openRead();
485
486       PersistenceConfig persistence = new PersistenceConfig();
487       persistence.setRoot(root);
488
489       new Config().configure(persistence, is,
490                              "com/caucho/amber/cfg/persistence-30.rnc");
491
492       for (PersistenceUnitConfig unitConfig : persistence.getUnitList()) {
493         try {
494           unitConfig.addAllClasses(classMap);
495
496           AmberPersistenceUnit unit = unitConfig.init(this, entityMappings);
497
498           _unitMap.put(unit.getName(), unit);
499         } catch (Throwable JavaDoc e) {
500           addException(e);
501
502           log.log(Level.WARNING, e.toString(), e);
503         }
504       }
505
506     } catch (ConfigException e) {
507       addException(e);
508
509       log.warning(e.getMessage());
510     } catch (Throwable JavaDoc e) {
511       addException(e);
512
513       log.log(Level.WARNING, e.toString(), e);
514     } finally {
515       try {
516         if (is != null)
517           is.close();
518       } catch (Throwable JavaDoc e) {
519       }
520     }
521   }
522
523   /**
524    * Lookup *.class files and add the corresponding
525    * fully qualified class names to the list.
526    */

527   public void lookupClasses(int rootNameLength,
528                             Path curr,
529                             HashMap JavaDoc<String JavaDoc, JClass> classMap,
530                             EntityMappingsConfig entityMappings)
531     throws Exception JavaDoc
532   {
533     Iterator JavaDoc<String JavaDoc> it = curr.iterator();
534
535     while (it.hasNext()) {
536
537       String JavaDoc s = it.next();
538
539       Path path = curr.lookup(s);
540
541       if (path.isDirectory()) {
542         lookupClasses(rootNameLength, path, classMap, entityMappings);
543       }
544       else if (s.endsWith(".class")) {
545         String JavaDoc packageName = curr.getPath().substring(rootNameLength);
546
547         packageName = packageName.replace('/', '.');
548
549         if (packageName.length() > 0)
550           packageName = packageName + '.';
551
552         String JavaDoc className = packageName + s.substring(0, s.length() - 6);
553
554         JClass type = _jClassLoader.forName(className);
555
556         if (type != null) {
557
558           boolean isEntity
559             = type.getAnnotation(javax.persistence.Entity.class) != null;
560           boolean isEmbeddable
561             = type.getAnnotation(javax.persistence.Embeddable.class) != null;
562           boolean isMappedSuperclass
563             = type.getAnnotation(javax.persistence.MappedSuperclass.class) != null;
564
565           EntityConfig entityConfig = null;
566
567           if (entityMappings != null)
568             entityConfig = entityMappings.getEntityConfig(className);
569
570           if (isEntity || isEmbeddable || isMappedSuperclass ||
571               (entityConfig != null)) {
572             classMap.put(className, type);
573           }
574         }
575       }
576     }
577   }
578 }
579
Popular Tags