001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.amber.manager;
031:
032: import com.caucho.amber.AmberRuntimeException;
033: import com.caucho.amber.cfg.*;
034: import com.caucho.amber.gen.AmberEnhancer;
035: import com.caucho.amber.gen.AmberGenerator;
036: import com.caucho.amber.type.*;
037: import com.caucho.bytecode.JClass;
038: import com.caucho.bytecode.JClassLoader;
039: import com.caucho.config.*;
040: import com.caucho.loader.*;
041: import com.caucho.loader.enhancer.EnhancerManager;
042: import com.caucho.loader.enhancer.ScanListener;
043: import com.caucho.util.*;
044: import com.caucho.vfs.*;
045: import com.caucho.webbeans.manager.*;
046:
047: import javax.sql.DataSource;
048: import javax.persistence.*;
049: import javax.persistence.spi.*;
050: import java.io.InputStream;
051: import java.net.*;
052: import java.util.*;
053: import java.util.logging.Level;
054: import java.util.logging.Logger;
055:
056: /**
057: * Environment-based container.
058: */
059: public class AmberContainer implements ScanListener,
060: EnvironmentListener {
061: private static final L10N L = new L10N(AmberContainer.class);
062: private static final Logger log = Logger
063: .getLogger(AmberContainer.class.getName());
064:
065: private static final EnvironmentLocal<AmberContainer> _localContainer = new EnvironmentLocal<AmberContainer>();
066:
067: private EnvironmentClassLoader _parentLoader;
068: private ClassLoader _tempLoader;
069: // private EnhancingClassLoader _enhancedLoader;
070: private AmberContainer _parentAmberContainer;
071:
072: private JClassLoader _jClassLoader;
073:
074: private AmberEnhancer _enhancer;
075:
076: private DataSource _dataSource;
077: private DataSource _readDataSource;
078: private DataSource _xaDataSource;
079:
080: private boolean _createDatabaseTables;
081:
082: private ArrayList<PersistenceUnitConfig> _unitConfigList = new ArrayList<PersistenceUnitConfig>();
083:
084: private HashMap<String, AmberPersistenceUnit> _unitMap = new HashMap<String, AmberPersistenceUnit>();
085:
086: private HashMap<String, EntityManagerFactory> _factoryMap = new HashMap<String, EntityManagerFactory>();
087:
088: private HashMap<String, EntityManager> _persistenceContextMap = new HashMap<String, EntityManager>();
089:
090: private HashMap<String, EmbeddableType> _embeddableMap = new HashMap<String, EmbeddableType>();
091:
092: private HashMap<String, EntityType> _entityMap = new HashMap<String, EntityType>();
093:
094: private HashMap<String, MappedSuperclassType> _mappedSuperclassMap = new HashMap<String, MappedSuperclassType>();
095:
096: private HashMap<String, ListenerType> _defaultListenerMap = new HashMap<String, ListenerType>();
097:
098: private HashMap<String, ArrayList<ListenerType>> _entityListenerMap = new HashMap<String, ArrayList<ListenerType>>();
099:
100: private Throwable _exception;
101:
102: private HashMap<String, Throwable> _embeddableExceptionMap = new HashMap<String, Throwable>();
103:
104: private HashMap<String, Throwable> _entityExceptionMap = new HashMap<String, Throwable>();
105:
106: private HashMap<String, Throwable> _listenerExceptionMap = new HashMap<String, Throwable>();
107:
108: private HashMap<Path, RootContext> _persistenceRootMap = new HashMap<Path, RootContext>();
109:
110: private ArrayList<RootContext> _pendingRootList = new ArrayList<RootContext>();
111:
112: private ArrayList<AmberPersistenceUnit> _pendingUnitList = new ArrayList<AmberPersistenceUnit>();
113:
114: private HashSet<URL> _persistenceURLSet = new HashSet<URL>();
115:
116: private ArrayList<String> _pendingClasses = new ArrayList<String>();
117:
118: private AmberContainer(ClassLoader loader) {
119: _parentAmberContainer = _localContainer.get(loader);
120: _parentLoader = Environment.getEnvironmentClassLoader(loader);
121: _localContainer.set(this , _parentLoader);
122:
123: _tempLoader = _parentLoader.getNewTempClassLoader();
124:
125: // --- ok
126:
127: // XXX: change after the 3.1.4 release
128: _jClassLoader = EnhancerManager.create(_parentLoader)
129: .getJavaClassLoader();
130: /*
131: _jClassLoader
132: = JClassLoaderWrapper.create(_parentLoader.getNewTempClassLoader());
133: */
134:
135: _enhancer = new AmberEnhancer(this );
136:
137: EnhancerManager.create(_parentLoader).addClassEnhancer(
138: _enhancer);
139:
140: if (_parentAmberContainer != null)
141: copyContainerDefaults(_parentAmberContainer);
142:
143: _parentLoader.addScanListener(this );
144:
145: Environment.addEnvironmentListener(this , _parentLoader);
146:
147: try {
148: if (_parentLoader instanceof DynamicClassLoader)
149: ((DynamicClassLoader) _parentLoader).make();
150: } catch (RuntimeException e) {
151: throw e;
152: } catch (Exception e) {
153: throw new RuntimeException(e);
154: }
155: }
156:
157: /**
158: * Returns the local container.
159: */
160: public static AmberContainer create() {
161: return create(Thread.currentThread().getContextClassLoader());
162: }
163:
164: /**
165: * Returns the local container.
166: */
167: public static AmberContainer create(ClassLoader loader) {
168: synchronized (_localContainer) {
169: AmberContainer container = _localContainer.getLevel(loader);
170:
171: if (container == null) {
172: container = new AmberContainer(loader);
173:
174: _localContainer.set(container, loader);
175: }
176:
177: return container;
178: }
179: }
180:
181: /**
182: * Returns the local container.
183: */
184: public static AmberContainer getCurrent() {
185: return getCurrent(Thread.currentThread()
186: .getContextClassLoader());
187: }
188:
189: /**
190: * Returns the current environment container.
191: */
192: public static AmberContainer getCurrent(ClassLoader loader) {
193: synchronized (_localContainer) {
194: return _localContainer.get(loader);
195: }
196: }
197:
198: /**
199: * Sets the primary data source.
200: */
201: public void setDataSource(DataSource dataSource) {
202: _dataSource = dataSource;
203: }
204:
205: /**
206: * Gets the primary data source.
207: */
208: public DataSource getDataSource() {
209: return _dataSource;
210: }
211:
212: /**
213: * Sets the read data source.
214: */
215: public void setReadDataSource(DataSource dataSource) {
216: _readDataSource = dataSource;
217: }
218:
219: /**
220: * Gets the read data source.
221: */
222: public DataSource getReadDataSource() {
223: return _readDataSource;
224: }
225:
226: /**
227: * Sets the xa data source.
228: */
229: public void setXADataSource(DataSource dataSource) {
230: _xaDataSource = dataSource;
231: }
232:
233: /**
234: * Gets the XA data source.
235: */
236: public DataSource getXADataSource() {
237: return _xaDataSource;
238: }
239:
240: /**
241: * True if database tables should be created automatically.
242: */
243: public boolean getCreateDatabaseTables() {
244: return _createDatabaseTables;
245: }
246:
247: /**
248: * True if database tables should be created automatically.
249: */
250: public void setCreateDatabaseTables(boolean isCreate) {
251: _createDatabaseTables = isCreate;
252: }
253:
254: /**
255: * Returns the parent loader
256: */
257: public ClassLoader getParentClassLoader() {
258: return _parentLoader;
259: }
260:
261: /**
262: * Returns the parent loader
263: */
264: public ClassLoader getEnhancedLoader() {
265: return _parentLoader;
266: }
267:
268: /**
269: * Returns the enhancer.
270: */
271: public AmberGenerator getGenerator() {
272: return _enhancer;
273: }
274:
275: /**
276: * Returns the persistence unit JNDI context.
277: */
278: public static String getPersistenceUnitJndiPrefix() {
279: return "java:comp/env/persistence/_amber_PersistenceUnit/";
280: }
281:
282: /**
283: * Returns the persistence unit JNDI context.
284: */
285: public static String getPersistenceContextJndiPrefix() {
286: //return "java:comp/env/persistence/PersistenceContext/";
287: return "java:comp/env/persistence/";
288: }
289:
290: /**
291: * Returns the JClassLoader.
292: */
293: public JClassLoader getJClassLoader() {
294: return _jClassLoader;
295: }
296:
297: private void copyContainerDefaults(AmberContainer parent) {
298: _dataSource = parent._dataSource;
299: _xaDataSource = parent._xaDataSource;
300: _readDataSource = parent._readDataSource;
301: _createDatabaseTables = parent._createDatabaseTables;
302: }
303:
304: public void init() {
305: }
306:
307: /**
308: * Returns the EmbeddableType for an introspected class.
309: */
310: public EmbeddableType getEmbeddable(String className) {
311: Throwable e = _embeddableExceptionMap.get(className);
312:
313: if (e != null)
314: throw new AmberRuntimeException(e);
315: else if (_exception != null) {
316: throw new AmberRuntimeException(_exception);
317: }
318:
319: return _embeddableMap.get(className);
320: }
321:
322: /**
323: * Returns the EntityType for an introspected class.
324: */
325: public EntityType getEntity(String className) {
326: Throwable e = _entityExceptionMap.get(className);
327:
328: if (e != null)
329: throw new AmberRuntimeException(e);
330: else if (_exception != null) {
331: throw new AmberRuntimeException(_exception);
332: }
333:
334: return _entityMap.get(className);
335: }
336:
337: /**
338: * Returns the MappedSuperclassType for an introspected class.
339: */
340: public MappedSuperclassType getMappedSuperclass(String className) {
341: Throwable e = _entityExceptionMap.get(className);
342:
343: if (e != null)
344: throw new AmberRuntimeException(e);
345: else if (_exception != null) {
346: throw new AmberRuntimeException(_exception);
347: }
348:
349: MappedSuperclassType type = _mappedSuperclassMap.get(className);
350:
351: return type;
352: }
353:
354: /**
355: * Returns the default ListenerType for an introspected class.
356: */
357: public ListenerType getDefaultListener(String className) {
358: if (true)
359: return null;
360:
361: Throwable e = _listenerExceptionMap.get(className);
362:
363: if (e != null)
364: throw new AmberRuntimeException(e);
365: else if (_exception != null) {
366: throw new AmberRuntimeException(_exception);
367: }
368:
369: return _defaultListenerMap.get(className);
370: }
371:
372: /**
373: * Returns the entity ListenerType for an introspected class.
374: */
375: public ListenerType getEntityListener(String className) {
376: if (true)
377: return null;
378:
379: Throwable e = _listenerExceptionMap.get(className);
380:
381: if (e != null)
382: throw new AmberRuntimeException(e);
383: else if (_exception != null) {
384: throw new AmberRuntimeException(_exception);
385: }
386:
387: ArrayList<ListenerType> listenerList;
388:
389: for (Map.Entry<String, ArrayList<ListenerType>> entry : _entityListenerMap
390: .entrySet()) {
391:
392: listenerList = entry.getValue();
393:
394: if (listenerList == null)
395: continue;
396:
397: for (ListenerType listener : listenerList) {
398: if (className.equals(listener.getBeanClass().getName()))
399: return listener;
400: }
401: }
402:
403: return null;
404: }
405:
406: /**
407: * Returns the listener for an introspected class.
408: */
409: public ListenerType getListener(String className) {
410: if (true)
411: return null;
412:
413: ListenerType listener = getDefaultListener(className);
414:
415: if (listener == null)
416: listener = getEntityListener(className);
417:
418: return listener;
419: }
420:
421: /**
422: * Returns the entity listeners for an entity.
423: */
424: public ArrayList<ListenerType> getEntityListeners(
425: String entityClassName) {
426: return null;
427:
428: // return _entityListenerMap.get(entityClassName);
429: }
430:
431: /**
432: * Adds an entity for an introspected class.
433: */
434: public void addEntityException(String className, Throwable e) {
435: _entityExceptionMap.put(className, e);
436: }
437:
438: /**
439: * Adds an entity for an introspected class.
440: */
441: public void addException(Throwable e) {
442: if (_exception == null) {
443: _exception = e;
444:
445: Environment.setConfigException(e);
446: }
447: }
448:
449: public Throwable getConfigException() {
450: return _exception;
451: }
452:
453: /**
454: * Adds an embeddable for an introspected class.
455: */
456: public void addEmbeddable(String className, EmbeddableType type) {
457: _embeddableMap.put(className, type);
458: }
459:
460: /**
461: * Adds an entity for an introspected class.
462: */
463: public void addEntity(String className, EntityType type) {
464: _entityMap.put(className, type);
465: }
466:
467: /**
468: * Adds a mapped superclass for an introspected class.
469: */
470: public void addMappedSuperclass(String className,
471: MappedSuperclassType type) {
472: _mappedSuperclassMap.put(className, type);
473: }
474:
475: /**
476: * Adds a default listener.
477: */
478: public void addDefaultListener(String className, ListenerType type) {
479: _defaultListenerMap.put(className, type);
480: }
481:
482: /**
483: * Adds an entity listener.
484: */
485: public void addEntityListener(String entityClassName,
486: ListenerType listenerType) {
487: ArrayList<ListenerType> listenerList = _entityListenerMap
488: .get(entityClassName);
489:
490: if (listenerList == null) {
491: listenerList = new ArrayList<ListenerType>();
492: _entityListenerMap.put(entityClassName, listenerList);
493: }
494:
495: listenerList.add(listenerType);
496: }
497:
498: /**
499: * Initialize the entity homes.
500: */
501: public void initEntityHomes() {
502: throw new UnsupportedOperationException();
503: }
504:
505: public AmberPersistenceUnit createPersistenceUnit(String name) {
506: AmberPersistenceUnit unit = new AmberPersistenceUnit(this , name);
507:
508: _unitMap.put(unit.getName(), unit);
509:
510: return unit;
511: }
512:
513: public void start() {
514: configurePersistenceRoots();
515: startPersistenceUnits();
516: }
517:
518: public AmberPersistenceUnit getPersistenceUnit(String name) {
519: if (_exception != null)
520: throw new AmberRuntimeException(_exception);
521:
522: return _unitMap.get(name);
523: }
524:
525: public EntityManagerFactory getEntityManagerFactory(String name) {
526: if (_exception != null)
527: throw new AmberRuntimeException(_exception);
528:
529: EntityManagerFactory factory = _factoryMap.get(name);
530: if (factory != null)
531: return factory;
532:
533: if (_pendingRootList.size() > 0)
534: configurePersistenceRoots();
535:
536: factory = _factoryMap.get(name);
537: if (factory != null)
538: return factory;
539:
540: AmberPersistenceUnit amberUnit = _unitMap.get(name);
541: if (amberUnit != null) {
542: factory = new AmberEntityManagerFactory(amberUnit);
543: _factoryMap.put(name, factory);
544: return factory;
545: }
546:
547: if ("".equals(name) && _factoryMap.size() == 1)
548: return _factoryMap.values().iterator().next();
549:
550: if ("".equals(name) && _unitMap.size() == 1) {
551: amberUnit = _unitMap.values().iterator().next();
552:
553: factory = new AmberEntityManagerFactory(amberUnit);
554: _factoryMap.put(name, factory);
555: return factory;
556: }
557:
558: if (_parentAmberContainer != null)
559: return _parentAmberContainer.getEntityManagerFactory(name);
560: else
561: return null;
562: }
563:
564: public EntityManager getPersistenceContext(String name) {
565: if (_exception != null)
566: throw new AmberRuntimeException(_exception);
567:
568: if ("".equals(name) && _unitConfigList.size() > 0)
569: name = _unitConfigList.get(0).getName();
570:
571: EntityManager context = _persistenceContextMap.get(name);
572: if (context != null)
573: return context;
574:
575: if (_pendingRootList.size() > 0)
576: configurePersistenceRoots();
577:
578: if ("".equals(name) && _unitConfigList.size() > 0)
579: name = _unitConfigList.get(0).getName();
580:
581: context = _persistenceContextMap.get(name);
582: if (context != null)
583: return context;
584:
585: AmberPersistenceUnit amberUnit = _unitMap.get(name);
586: if (amberUnit != null) {
587: context = new EntityManagerProxy(amberUnit);
588: _persistenceContextMap.put(name, context);
589:
590: return context;
591: }
592:
593: return null;
594: }
595:
596: /**
597: * Adds a persistence root.
598: */
599: public void addPersistenceUnit(Path root) {
600: if (_persistenceRootMap.get(root) != null)
601: return;
602:
603: RootContext context = new RootContext(root);
604: _persistenceRootMap.put(root, context);
605: _pendingRootList.add(context);
606: }
607:
608: /**
609: * Adds the URLs for the classpath.
610: */
611: public void configurePersistenceRoots() {
612: Thread thread = Thread.currentThread();
613: ClassLoader oldLoader = thread.getContextClassLoader();
614:
615: try {
616: // jpa/1630
617: // thread.setContextClassLoader(_tempLoader);
618: thread.setContextClassLoader(_parentLoader);
619:
620: ArrayList<RootContext> rootList = new ArrayList<RootContext>(
621: _pendingRootList);
622: _pendingRootList.clear();
623:
624: for (RootContext rootContext : rootList) {
625: configureRoot(rootContext);
626: }
627: } finally {
628: thread.setContextClassLoader(oldLoader);
629: }
630: }
631:
632: private void configureRoot(RootContext rootContext) {
633: Path root = rootContext.getRoot();
634:
635: try {
636: Path ormXml = root.lookup("META-INF/orm.xml");
637:
638: EntityMappingsConfig entityMappings = configureMappingFile(
639: root, ormXml);
640:
641: ArrayList<PersistenceUnitConfig> unitList = parsePersistenceConfig(root);
642:
643: if (unitList == null)
644: return;
645:
646: HashMap<String, JClass> classMap = new HashMap<String, JClass>();
647:
648: for (PersistenceUnitConfig unitConfig : unitList) {
649: Class provider = unitConfig.getProvider();
650: if (provider != null
651: && !AmberPersistenceProvider.class
652: .equals(provider)) {
653: addProviderUnit(unitConfig);
654:
655: continue;
656: }
657:
658: try {
659: if (log.isLoggable(Level.CONFIG))
660: log.config("Amber PersistenceUnit["
661: + unitConfig.getName()
662: + "] configuring "
663: + rootContext.getRoot().getURL());
664:
665: if (!unitConfig.isExcludeUnlistedClasses()) {
666: classMap.clear();
667:
668: for (String className : rootContext
669: .getClassNameList())
670: lookupClass(className, classMap,
671: entityMappings);
672:
673: unitConfig.addAllClasses(classMap);
674: }
675:
676: ArrayList<EntityMappingsConfig> entityMappingsList = new ArrayList<EntityMappingsConfig>();
677:
678: if (entityMappings != null)
679: entityMappingsList.add(entityMappings);
680:
681: // jpa/0s2n: <jar-file>
682: for (String fileName : unitConfig.getJarFiles()) {
683: JarPath jarFile;
684:
685: Path parent = root;
686:
687: if (root instanceof JarPath) {
688: parent = ((JarPath) root).getContainer()
689: .getParent();
690: }
691:
692: jarFile = JarPath.create(parent
693: .lookup(fileName));
694:
695: classMap.clear();
696:
697: // lookupJarClasses(jarFile, classMap, entityMappings);
698:
699: unitConfig.addAllClasses(classMap);
700: }
701:
702: // jpa/0s2l: custom mapping-file.
703: for (String fileName : unitConfig.getMappingFiles()) {
704: Path mappingFile = root.lookup(fileName);
705:
706: EntityMappingsConfig mappingFileConfig = configureMappingFile(
707: root, mappingFile);
708:
709: if (mappingFileConfig != null) {
710: entityMappingsList.add(mappingFileConfig);
711:
712: classMap.clear();
713: /*
714: lookupClasses(root.getPath().length(), root, classMap,
715: mappingFileConfig);
716: */
717: unitConfig.addAllClasses(classMap);
718: }
719: }
720:
721: AmberPersistenceUnit unit = unitConfig.init(this ,
722: entityMappingsList);
723:
724: _pendingUnitList.add(unit);
725:
726: _unitMap.put(unit.getName(), unit);
727: } catch (Exception e) {
728: addException(e);
729:
730: log.log(Level.WARNING, e.toString(), e);
731: }
732: }
733: } catch (RuntimeException e) {
734: throw e;
735: } catch (Exception e) {
736: throw ConfigException.create(e);
737: }
738: }
739:
740: /**
741: * Adds the URLs for the classpath.
742: */
743: public void startPersistenceUnits() {
744: Thread thread = Thread.currentThread();
745: ClassLoader oldLoader = thread.getContextClassLoader();
746:
747: try {
748: // jpa/1630
749: // thread.setContextClassLoader(_tempLoader);
750: thread.setContextClassLoader(_parentLoader);
751:
752: ArrayList<AmberPersistenceUnit> unitList = new ArrayList<AmberPersistenceUnit>(
753: _pendingUnitList);
754: _pendingUnitList.clear();
755:
756: for (AmberPersistenceUnit unit : unitList) {
757: unit.initEntityHomes();
758: }
759: } finally {
760: thread.setContextClassLoader(oldLoader);
761: }
762: }
763:
764: private void addProviderUnit(PersistenceUnitConfig unit) {
765: try {
766: Class cl = unit.getProvider();
767:
768: if (log.isLoggable(Level.CONFIG)) {
769: log.config("JPA PersistenceUnit[" + unit.getName()
770: + "] handled by " + cl.getName());
771: }
772:
773: PersistenceProvider provider = (PersistenceProvider) cl
774: .newInstance();
775:
776: EntityManagerFactory factory;
777:
778: Map props = null;
779: factory = provider.createContainerEntityManagerFactory(
780: unit, null);
781:
782: String unitName = unit.getName();
783:
784: if (factory == null)
785: throw new ConfigException(L.l(
786: "'{0}' must return an EntityManagerFactory",
787: provider.getClass().getName()));
788:
789: if (log.isLoggable(Level.FINE)) {
790: log
791: .fine(L
792: .l(
793: "Amber creating persistence unit '{0}' created with provider '{1}'",
794: unitName, provider.getClass()
795: .getName()));
796: }
797:
798: _factoryMap.put(unitName, factory);
799: _persistenceContextMap.put(unitName, factory
800: .createEntityManager(props));
801:
802: WebBeansContainer webBeans = WebBeansContainer
803: .create(_parentLoader);
804: webBeans.addComponent(new EntityManagerFactoryComponent(
805: provider, unit, unitName, factory));
806: webBeans.addComponent(new EntityManagerComponent(factory,
807: unitName, props));
808: } catch (RuntimeException e) {
809: throw e;
810: } catch (Exception e) {
811: throw ConfigException.create(e);
812: }
813: }
814:
815: /**
816: * Adds a persistence root.
817: */
818: private ArrayList<PersistenceUnitConfig> parsePersistenceConfig(
819: Path root) {
820: Path persistenceXml = root.lookup("META-INF/persistence.xml");
821:
822: if (!persistenceXml.canRead())
823: return null;
824:
825: persistenceXml.setUserPath(persistenceXml.getURL());
826:
827: InputStream is = null;
828:
829: try {
830: is = persistenceXml.openRead();
831:
832: PersistenceConfig persistence = new PersistenceConfig();
833: persistence.setRoot(root);
834:
835: new Config().configure(persistence, is,
836: "com/caucho/amber/cfg/persistence-30.rnc");
837:
838: ArrayList<PersistenceUnitConfig> unitList = persistence
839: .getUnitList();
840:
841: _unitConfigList.addAll(unitList);
842:
843: return unitList;
844: } catch (RuntimeException e) {
845: throw e;
846: } catch (Exception e) {
847: throw LineConfigException.create(e);
848: } finally {
849: try {
850: if (is != null)
851: is.close();
852: } catch (Exception e) {
853: }
854: }
855: }
856:
857: //
858: // private
859:
860: //
861: // Configures the default orm.xml or mapping files specified with
862: // mapping-file tags within a persistence-unit.
863: //
864: private EntityMappingsConfig configureMappingFile(Path root,
865: Path xmlFile) throws Exception {
866: EntityMappingsConfig entityMappings = null;
867:
868: if (xmlFile.exists()) {
869: InputStream is = xmlFile.openRead();
870:
871: entityMappings = new EntityMappingsConfig();
872: entityMappings.setRoot(root);
873:
874: new Config().configure(entityMappings, is,
875: "com/caucho/amber/cfg/mapping-30.rnc");
876: }
877:
878: return entityMappings;
879: }
880:
881: private void lookupClass(String className,
882: HashMap<String, JClass> classMap,
883: EntityMappingsConfig entityMappings) throws Exception {
884: JClass type = _jClassLoader.forName(className);
885:
886: if (type != null) {
887: boolean isEntity = type
888: .getAnnotation(javax.persistence.Entity.class) != null;
889: boolean isEmbeddable = type
890: .getAnnotation(javax.persistence.Embeddable.class) != null;
891: boolean isMappedSuperclass = type
892: .getAnnotation(javax.persistence.MappedSuperclass.class) != null;
893:
894: MappedSuperclassConfig mappedSuperclassOrEntityConfig = null;
895:
896: if (entityMappings != null) {
897: mappedSuperclassOrEntityConfig = entityMappings
898: .getEntityConfig(className);
899:
900: if (mappedSuperclassOrEntityConfig == null)
901: mappedSuperclassOrEntityConfig = entityMappings
902: .getMappedSuperclass(className);
903: }
904:
905: if (isEntity || isEmbeddable || isMappedSuperclass
906: || (mappedSuperclassOrEntityConfig != null)) {
907: classMap.put(className, type);
908: }
909: }
910: }
911:
912: //
913: // ScanListener
914: //
915:
916: /**
917: * Returns true if the root is a valid scannable root.
918: */
919: public boolean isRootScannable(Path root) {
920: if (!root.lookup("META-INF/persistence.xml").canRead())
921: return false;
922:
923: RootContext context = _persistenceRootMap.get(root);
924:
925: if (context == null) {
926: context = new RootContext(root);
927: _pendingRootList.add(context);
928: _persistenceRootMap.put(root, context);
929: }
930:
931: if (context.isScanComplete())
932: return false;
933: else {
934: context.setScanComplete(true);
935:
936: return true;
937: }
938: }
939:
940: public boolean isScanMatch(CharBuffer annotationName) {
941: if (annotationName.matches("javax.persistence.Entity"))
942: return true;
943: else if (annotationName.matches("javax.persistence.Embeddable"))
944: return true;
945: else if (annotationName
946: .matches("javax.persistence.MappedSuperclass"))
947: return true;
948: else
949: return false;
950: }
951:
952: /**
953: * Callback to note the class matches
954: */
955: public void classMatchEvent(EnvironmentClassLoader loader,
956: Path root, String className) {
957: RootContext context = _persistenceRootMap.get(root);
958:
959: if (context == null) {
960: context = new RootContext(root);
961: _persistenceRootMap.put(root, context);
962: _pendingRootList.add(context);
963: }
964:
965: context.addClassName(className);
966: }
967:
968: //
969: // EnvironmentListener
970: //
971:
972: /**
973: * Handles the environment config phase
974: */
975: public void environmentConfig(EnvironmentClassLoader loader) {
976: // config();
977: }
978:
979: /**
980: * Handles the case where the environment is starting (after init).
981: */
982: public void environmentStart(EnvironmentClassLoader loader) {
983: start();
984: }
985:
986: /**
987: * Handles the case where the environment is stopping
988: */
989: public void environmentStop(EnvironmentClassLoader loader) {
990: }
991:
992: public String toString() {
993: return "AmberContainer[" + _parentLoader.getId() + "]";
994: }
995: }
|