001: /**
002: * EasyBeans
003: * Copyright (C) 2006 Bull S.A.S.
004: * Contact: easybeans@ow2.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: PersistenceUnitManager.java 1970 2007-10-16 11:49:25Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.ow2.easybeans.persistence;
025:
026: import java.util.HashMap;
027: import java.util.Iterator;
028: import java.util.Map;
029:
030: import javax.persistence.EntityManager;
031: import javax.persistence.EntityManagerFactory;
032: import javax.persistence.PersistenceContextType;
033:
034: import org.ow2.easybeans.persistence.api.EZBPersistenceUnitManager;
035: import org.ow2.easybeans.persistence.xml.JPersistenceUnitInfo;
036:
037: /**
038: * This class manages persistence units ands allow to return EntityManager or
039: * EntityManagerFactory.
040: * @author Florent Benoit
041: */
042: public class PersistenceUnitManager implements
043: EZBPersistenceUnitManager {
044:
045: /**
046: * List of persistence unit objects managed by their name.
047: */
048: private Map<String, JPersistenceContext> persistenceContexts = null;
049:
050: /**
051: * Persistence unit infos.
052: */
053: private JPersistenceUnitInfo[] persistenceUnitInfos;
054:
055: /**
056: * Build a new manager with given persistence units.
057: * @param persistenceUnitInfos a list of persistence unit infos.
058: */
059: public PersistenceUnitManager(
060: final JPersistenceUnitInfo[] persistenceUnitInfos) {
061: this .persistenceUnitInfos = persistenceUnitInfos;
062: this .persistenceContexts = new HashMap<String, JPersistenceContext>();
063: // Add each object to the map
064: addExtraPersistenceUnitInfos(persistenceUnitInfos);
065: }
066:
067: /**
068: * Adds new persistence unit infos to this persistence unit manager.<br>
069: * Note: The persistence unit name have to be different from existing persistence units.
070: * @param newPersistenceUnitInfos a list of persistence unit infos.
071: */
072: public void addExtraPersistenceUnitInfos(
073: final JPersistenceUnitInfo[] newPersistenceUnitInfos) {
074: if (newPersistenceUnitInfos != null) {
075: for (JPersistenceUnitInfo pUnitInfo : newPersistenceUnitInfos) {
076: // get unit name
077: String persistenceUnitName = pUnitInfo
078: .getPersistenceUnitName();
079:
080: // Check existing ?
081: JPersistenceContext jPersistenceContext = persistenceContexts
082: .get(persistenceUnitName);
083:
084: // Existing one found, add new persistence unit infos on it
085: if (jPersistenceContext != null) {
086: throw new IllegalArgumentException(
087: "There is already an existing persistence unit name named '"
088: + persistenceUnitName
089: + "' in this persistence unit manager.");
090: }
091:
092: // Add it
093: persistenceContexts.put(persistenceUnitName,
094: new JPersistenceContext(pUnitInfo));
095: }
096: }
097: }
098:
099: /**
100: * Gets the persistence context associated to a given persistence unit name.
101: * @param unitName the name of the persistence unit object.
102: * @return the object which is found by matching the expected name.
103: */
104: private JPersistenceContext getPersistenceContext(
105: final String unitName) {
106: if (unitName == null || unitName.equals("")) {
107: if (persistenceContexts.size() == 0) {
108: throw new IllegalArgumentException(
109: "No persistence-unit defined");
110: } else if (persistenceContexts.size() > 1) {
111: throw new IllegalArgumentException(
112: "Too many persistence-unit defined, cannot take the default one.");
113: }
114: return persistenceContexts.values().iterator().next();
115: }
116: // else, return the unit associated to the given name
117: JPersistenceContext persistenceContext = persistenceContexts
118: .get(unitName);
119: if (persistenceContext == null) {
120: throw new IllegalArgumentException(
121: "No persistence-unit with name '" + unitName
122: + "' defined.");
123: }
124: return persistenceContext;
125: }
126:
127: /**
128: * Gets an entity manager for the given unit name and the extra attributes.
129: * @param unitName the name of the persistence unit
130: * @param type the type of the persistence context
131: * @return entity manager corresponding to arguments
132: */
133: public EntityManager getEntityManager(final String unitName,
134: final PersistenceContextType type) {
135: // TODO: Manage also extended persistence context;
136: return getPersistenceContext(unitName).getTxEntityManager();
137: }
138:
139: /**
140: * Gets an entity manager factory for the given unit name.
141: * @param unitName the name of the persistence unit
142: * @return entity manager factory.
143: */
144: public EntityManagerFactory getEntityManagerFactory(
145: final String unitName) {
146: return getPersistenceContext(unitName)
147: .getEntityManagerFactory();
148: }
149:
150: /**
151: * Create a new EntityManager on each PersistenceContext. (Will be used for
152: * the method lifecycle)
153: */
154: public void addCurrent() {
155: for (Iterator<JPersistenceContext> itContext = persistenceContexts
156: .values().iterator(); itContext.hasNext();) {
157: JPersistenceContext pContext = itContext.next();
158: pContext.addCurrent();
159: }
160: }
161:
162: /**
163: * Sets back to the previous entity manager and close the current entity
164: * manager for each persistence context.
165: */
166: public void closeCurrentAndReturnToPrevious() {
167: for (Iterator<JPersistenceContext> itContext = persistenceContexts
168: .values().iterator(); itContext.hasNext();) {
169: JPersistenceContext pContext = itContext.next();
170: pContext.closeCurrentAndReturnToPrevious();
171: }
172: }
173:
174: /**
175: * Merge the persistence context of a an other persistent unit manager in
176: * this one. Note that as specified in chapter 6.2.2 (persistence unit
177: * scope), an EAR level component level will only be seen by a subcomponent
178: * if it was not redefined. In our case : don't merge the given unit-name if
179: * the current manager defines this unit-name.
180: * @param otherEZBPersistenceUnitManager the other persistence unit manager
181: * that will be merged into this one.
182: */
183: public void merge(
184: final EZBPersistenceUnitManager otherEZBPersistenceUnitManager) {
185: // do nothing if the given manager is null
186: if (otherEZBPersistenceUnitManager == null) {
187: return;
188: }
189: PersistenceUnitManager otherPersistenceUnitManager = null;
190: if (otherEZBPersistenceUnitManager instanceof PersistenceUnitManager) {
191: otherPersistenceUnitManager = (PersistenceUnitManager) otherEZBPersistenceUnitManager;
192: } else {
193: return;
194: }
195:
196: // get all persistence contexts of the given manager
197: for (Iterator<String> itContext = otherPersistenceUnitManager.persistenceContexts
198: .keySet().iterator(); itContext.hasNext();) {
199: String unitName = itContext.next();
200: // existing in our manager?
201: JPersistenceContext pContext = persistenceContexts
202: .get(unitName);
203: if (pContext == null) {
204: // add it (not existing)
205: persistenceContexts.put(unitName,
206: otherPersistenceUnitManager.persistenceContexts
207: .get(unitName));
208: }
209: }
210:
211: }
212:
213: /**
214: * Gets the persistence unit infos used by this manager.
215: * @return the persistence unit infos used by this manager.
216: */
217: public JPersistenceUnitInfo[] getPersistenceUnitInfos() {
218: return persistenceUnitInfos;
219: }
220:
221: }
|