001: /**
002: * Speedo: an implementation of JDO compliant personality on top of JORM generic
003: * I/O sub-system.
004: * Copyright (C) 2001-2004 France Telecom R&D
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 of the License, or (at your option) 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 USA
019: *
020: *
021: *
022: * Contact: speedo@objectweb.org
023: *
024: * Authors: S.Chassande-Barrioz.
025: *
026: */package org.objectweb.speedo.pm.lib;
027:
028: import org.objectweb.speedo.pm.api.POManagerItf;
029: import org.objectweb.speedo.pm.api.POManagerFactoryItf;
030: import org.objectweb.speedo.pm.api.POManagerSwitchItf;
031:
032: import java.util.ArrayList;
033: import java.util.Collection;
034: import java.util.Iterator;
035: import java.util.List;
036: import java.util.Collections;
037:
038: /**
039: * This class is an implementation of the POManagerSwitchItf based on the use
040: * of a ThreadLocal field. This field contains an instance of POManagerItf of an
041: * ArrayList of POManagerItf. A POManagerSwitch is a fractal component without
042: * bindings.
043: *
044: * @author S.Chassande-Barrioz
045: */
046: public class POManagerSwitchImpl implements POManagerSwitchItf {
047:
048: protected ThreadLocal pms = new ThreadLocal();
049:
050: public final static String BIND_ERROR_MSG = "Impossible to associated to POManagerItf linked to the same PersistenceManagerFactory in the same context (thread)";
051:
052: // IMPLEMENTATION OF THE POManagerSwitchItf INTERFACE //
053: //----------------------------------------------------//
054:
055: /**
056: * @param pmf is persistent manager factory which manages the returned
057: * po manager.
058: * @return the POManagerItf managed by the given persistence manager factory
059: * and bound to current the context, or the null value if there is no
060: * POManagerItf.
061: */
062: public POManagerItf lookup(POManagerFactoryItf pmf) {
063: Object o = pms.get();
064: if (o == null) {
065: return null;
066: } else if (o instanceof POManagerItf) {
067: if (((POManagerItf) o).getPOManagerFactory() == pmf)
068: return (POManagerItf) o;
069: } else {
070: for (Iterator it = ((List) o).iterator(); it.hasNext();) {
071: POManagerItf pm = (POManagerItf) it.next();
072: if (pm.getPOManagerFactory() == pmf)
073: return pm;
074: }
075: }
076: return null;
077: }
078:
079: /**
080: * It assignes a POManagerItf to the current context.
081: * @param pm is the POManagerItf
082: */
083: public void bind(POManagerItf pm) {
084: Object o = pms.get();
085: if (o == null) {
086: pms.set(pm);
087: } else if (o instanceof POManagerItf) {
088: // There is one POManagerItf, then check if the old and the new
089: // po manager are managed by the same PMF.
090: POManagerItf pm1 = (POManagerItf) o;
091: if (pm1.getPOManagerFactory() == pm.getPOManagerFactory()) {
092: pms.set(pm);
093: } else {
094: // Put the old and the new in a List
095: ArrayList al = new ArrayList(3);
096: al.add(pm1);
097: al.add(pm);
098: pms.set(al);
099: }
100: } else {
101: // The element is a list of POManagerItf instances, then check if
102: // there is a po manager linked to the same PersistenceManagerFactory
103: List l = (List) o;
104: for (Iterator it = l.iterator(); it.hasNext();) {
105: if (((POManagerItf) it.next()).getPOManagerFactory() == pm
106: .getPOManagerFactory()) {
107: it.remove();
108: }
109: }
110: //No element with the same pmf, then add the po manager
111: ((List) o).add(pm);
112: }
113: }
114:
115: /**
116: * It clears the list of POManagerItf for the current context.
117: */
118: public void clear() {
119: pms.set(null);
120: }
121:
122: /**
123: * It clears a POManagerItf for the current context.
124: */
125: public boolean unbind(POManagerItf pm) {
126: Object o = pms.get();
127: if (o == null) {
128: return false;
129: } else if (o instanceof POManagerItf) {
130: if (o == pm) {
131: pms.set(null);
132: return true;
133: }
134: } else if (o instanceof Collection) {
135: return ((Collection) o).remove(pm);
136: }
137: return false;
138: }
139:
140: public boolean unbind(POManagerFactoryItf pmf) {
141: Object o = pms.get();
142: if (o == null) {
143: return false;
144: } else if (o instanceof POManagerItf) {
145: if (((POManagerItf) o).getPOManagerFactory() == pmf) {
146: pms.set(null);
147: return true;
148: }
149: } else { // The element is a list of POManagerItf instances
150: for (Iterator it = ((List) o).iterator(); it.hasNext();) {
151: if (((POManagerItf) it.next()).getPOManagerFactory() == pmf) {
152: it.remove();
153: return true;
154: }
155: }
156: }
157: return false;
158: }
159:
160: /**
161: * @return all POManagerItf instances bound with the current context
162: */
163: public Collection entries() {
164: Object o = pms.get();
165: if (o instanceof POManagerItf)
166: return Collections.singletonList(o);
167: else
168: return (Collection) o;
169: }
170: }
|