001: /**
002: * Copyright (C) 2001-2005 France Telecom R&D
003: */package org.objectweb.speedo.pm.lib;
004:
005: import org.objectweb.fractal.api.Component;
006: import org.objectweb.fractal.api.NoSuchInterfaceException;
007: import org.objectweb.fractal.api.control.BindingController;
008: import org.objectweb.jorm.api.PException;
009: import org.objectweb.jorm.api.PMapper;
010: import org.objectweb.perseus.cache.api.CacheException;
011: import org.objectweb.perseus.cache.api.CacheManager;
012: import org.objectweb.perseus.cache.api.UnbindManager;
013: import org.objectweb.perseus.persistence.api.TransactionalPersistenceManager;
014: import org.objectweb.perseus.pool.api.Pool;
015: import org.objectweb.speedo.api.ExceptionHelper;
016: import org.objectweb.speedo.lib.Personality;
017: import org.objectweb.speedo.mapper.api.ConnectionSpecFactory;
018: import org.objectweb.speedo.mapper.api.JormFactory;
019: import org.objectweb.speedo.mim.api.PersistentObjectItf;
020: import org.objectweb.speedo.pm.api.POManagerItf;
021: import org.objectweb.speedo.pm.api.POManagerFactoryItf;
022: import org.objectweb.speedo.pm.api.POManagerSwitchItf;
023: import org.objectweb.speedo.query.api.QueryManager;
024: import org.objectweb.speedo.sequence.api.SequenceManager;
025: import org.objectweb.util.monolog.api.BasicLevel;
026: import org.objectweb.util.monolog.api.Logger;
027:
028: import java.util.Collection;
029: import java.util.Properties;
030:
031: import javax.jdo.JDODataStoreException;
032: import javax.jdo.JDOFatalInternalException;
033:
034: /**
035: * Is a factory of POManagerItf. This primitive component exports the
036: * POManagerFactoryItf interface, permitting to manage the po manager
037: * allocations. Due to a high cost of POManagerItf allocation, the unsused
038: * POManagerItf are pooled. For this reason, the AbstractManagerFactory uses
039: * a Pool of POManagerItf. The AbstractPOManagerFactory manages also the
040: * attachement of POManagerItf to the current thread through a
041: * POManagerSwitchItf.
042: *
043: * @see org.objectweb.speedo.pm.api.POManagerItf
044: * @see org.objectweb.speedo.pm.api.POManagerFactoryItf
045: * @see org.objectweb.speedo.pm.api.POManagerSwitchItf
046: *
047: * @author S.Chassande-Barrioz
048: */
049: public abstract class AbstractPOManagerFactory implements
050: POManagerFactoryItf, BindingController {
051: public final static String MAPPER_BINDING = "mapper";
052: public final static String JORM_FACTORY_BINDING = "jorm-factory";
053: public final static String PM_POOL_BINDING = "po-manager-pool";
054: public final static String PO_MANAGER_SWITCH_BINDING = "po-manager-switch";
055: public final static String TPM_BINDING = "transactional-persistence-manager";
056: public final static String CACHE_M_BINDING = "cache-manager";
057: public final static String UNBIND_M_BINDING = "unbind-manager";
058: public final static String COMPONENT_BINDING = "component";
059: public final static String SEQUENCE_M_BINDING = "sequence-manager";
060: public final static String QUERY_M_BINDING = "query-manager";
061: protected final static int GETMAXPOOL = 100;
062: protected boolean imbricatedAuthorized = true;
063: /**
064: * Pool of PersistenceManager
065: */
066: protected Pool managedPM = null;
067: /**
068: * Manages the log's traces
069: */
070: protected Logger logger = null;
071: /**
072: * JORM object encapsulating the datastore
073: */
074: protected PMapper mapper = null;
075: /**
076: * The properties of the PMF
077: */
078: protected Properties connectionProperties = null;
079: /**
080: * The PMS managing the association PM / thread
081: */
082: protected POManagerSwitchItf pms = null;
083: /**
084: * The java reference to the current component
085: */
086: protected Object _this = null;
087: /**
088: * Information about the data store connection
089: */
090: protected ConnectionSpecFactory csf = null;
091: /**
092: * The fractal component status
093: */
094: protected boolean started = false;
095: /**
096: * The L2 cache containing persistent objects.
097: */
098: protected CacheManager cacheManager = null;
099: /**
100: * The L2 cache containing persistent objects.
101: */
102: protected UnbindManager unbindManager = null;
103: /**
104: * The factory initializing JORM structure (Mapping, Binder, PNC, ...)
105: */
106: protected JormFactory jormFactory = null;
107: /**
108: * The perseus component managing concurrency, caching and persitency.
109: */
110: protected TransactionalPersistenceManager tpm = null;
111: /**
112: * The query manager
113: */
114: protected QueryManager queryManager = null;
115: /**
116: * Speedo component managing the sequence (datastore or memory)
117: */
118: protected SequenceManager sequenceManager = null;
119: protected Personality personality;
120:
121: public AbstractPOManagerFactory(Personality p) {
122: connectionProperties = new Properties();
123: personality = p;
124: }
125:
126: protected void start() {
127: started = true;
128: }
129:
130: protected POManagerFactoryItf getThis() {
131: if (_this == null) {
132: throw new JDODataStoreException(
133: "Cannot provides a PersistenceManager without a reference to the component");
134: } else if (_this instanceof Component) {
135: try {
136: _this = ((Component) _this )
137: .getFcInterface("po-manager-factory");
138: } catch (NoSuchInterfaceException e) {
139: throw new JDODataStoreException(
140: "Cannot provides a PersistenceManager ",
141: new Exception[] { e });
142: }
143: }
144: return (POManagerFactoryItf) _this ;
145: }
146:
147: /**
148: * Verify that an instance is persistence capable.
149: * @param pc the object to test.
150: * @exception RuntimeException if the object is not persistence capable.
151: */
152: protected void assertIsPO(Object pc, String cmd) {
153: if (!(pc instanceof PersistentObjectItf)) {
154: if (pc == null) {
155: throw personality
156: .newUserRuntimeException("Null persistent object instance specified");
157: } else if (pc.getClass().isArray()
158: || pc instanceof Collection) {
159: throw personality
160: .newUserRuntimeException("You must use the "
161: + cmd
162: + "All method with a multivalued parameter: "
163: + pc);
164: } else {
165: throw personality
166: .newUserRuntimeException("The object is not a PersistentObjectItf, beware to : "
167: + pc);
168: }
169: }
170: }
171:
172: // IMPLEMENTATION OF THE UserBindingController INTERFACE //
173: //-------------------------------------------------------//
174:
175: public String[] listFc() {
176: return new String[] { PM_POOL_BINDING, MAPPER_BINDING,
177: PO_MANAGER_SWITCH_BINDING, CACHE_M_BINDING,
178: UNBIND_M_BINDING, JORM_FACTORY_BINDING, TPM_BINDING,
179: SEQUENCE_M_BINDING };
180: }
181:
182: public Object lookupFc(String s) {
183: if (PM_POOL_BINDING.equals(s))
184: return managedPM;
185: else if (MAPPER_BINDING.equals(s))
186: return mapper;
187: else if (PO_MANAGER_SWITCH_BINDING.equals(s))
188: return pms;
189: else if (CACHE_M_BINDING.equals(s))
190: return cacheManager;
191: else if (UNBIND_M_BINDING.equals(s))
192: return unbindManager;
193: else if (JORM_FACTORY_BINDING.equals(s))
194: return jormFactory;
195: else if (TPM_BINDING.equals(s))
196: return tpm;
197: else if (SEQUENCE_M_BINDING.equals(s))
198: return sequenceManager;
199: else if (QUERY_M_BINDING.equals(s))
200: return queryManager;
201: else
202: return null;
203: }
204:
205: public void bindFc(String s, Object o) {
206: if ("logger".equals(s)) {
207: logger = (Logger) o;
208: } else if (PM_POOL_BINDING.equals(s)) {
209: managedPM = (Pool) o;
210: } else if (MAPPER_BINDING.equals(s)) {
211: mapper = (PMapper) o;
212: } else if (PO_MANAGER_SWITCH_BINDING.equals(s)) {
213: pms = (POManagerSwitchItf) o;
214: } else if (CACHE_M_BINDING.equals(s)) {
215: cacheManager = (CacheManager) o;
216: } else if (UNBIND_M_BINDING.equals(s)) {
217: unbindManager = (UnbindManager) o;
218: } else if (COMPONENT_BINDING.equals(s)) {
219: _this = o;
220: } else if (JORM_FACTORY_BINDING.equals(s)) {
221: jormFactory = (JormFactory) o;
222: } else if (TPM_BINDING.equals(s)) {
223: tpm = (TransactionalPersistenceManager) o;
224: } else if (SEQUENCE_M_BINDING.equals(s)) {
225: sequenceManager = (SequenceManager) o;
226: } else if (QUERY_M_BINDING.equals(s)) {
227: queryManager = (QueryManager) o;
228: }
229: }
230:
231: public void unbindFc(String s) {
232: if (PM_POOL_BINDING.equals(s)) {
233: managedPM = null;
234: } else if (MAPPER_BINDING.equals(s)) {
235: mapper = null;
236: } else if (PO_MANAGER_SWITCH_BINDING.equals(s)) {
237: pms = null;
238: } else if (CACHE_M_BINDING.equals(s)) {
239: cacheManager = null;
240: } else if (UNBIND_M_BINDING.equals(s)) {
241: unbindManager = null;
242: } else if (JORM_FACTORY_BINDING.equals(s)) {
243: jormFactory = null;
244: } else if (TPM_BINDING.equals(s)) {
245: tpm = null;
246: } else if (SEQUENCE_M_BINDING.equals(s)) {
247: sequenceManager = null;
248: } else if (QUERY_M_BINDING.equals(s)) {
249: queryManager = null;
250: }
251: }
252:
253: // IMPLEMENTATION OF THE POManagerFactoryItf INTERFACE //
254: //-----------------------------------------------------//
255:
256: public POManagerItf lookup() {
257: return pms.lookup(getThis());
258: }
259:
260: public void bindPM2Thread(POManagerItf pm) {
261: if (logger.isLoggable(BasicLevel.DEBUG)) {
262: logger.log(BasicLevel.DEBUG, "Bind a pm to the thread: "
263: + pm);
264: }
265: pms.bind(pm);
266: }
267:
268: public void unbindPM() {
269: if (logger.isLoggable(BasicLevel.DEBUG)) {
270: logger.log(BasicLevel.DEBUG,
271: "Unbind the current PM from the thread");
272: }
273: pms.unbind(getThis());
274: }
275:
276: public void poManagerClosed(POManagerItf pr) {
277: try {
278: if (logger.isLoggable(BasicLevel.DEBUG)) {
279: logger.log(BasicLevel.DEBUG,
280: "Unbind a PM from the thread: " + pr);
281: }
282: pms.unbind(pr);
283: managedPM.releaseResource(pr);
284: } catch (Exception e) {
285: throw new JDOFatalInternalException(
286: "Impossible to release this PersistenceManager in the pool.",
287: new Exception[] { ExceptionHelper.getNested(e) });
288: }
289: }
290:
291: public SequenceManager getSequenceManager() {
292: return sequenceManager;
293: }
294:
295: public void setSequenceManager(SequenceManager sequenceManager) {
296: this .sequenceManager = sequenceManager;
297: }
298:
299: public QueryManager getQueryManager() {
300: return queryManager;
301: }
302:
303: public void setQueryManager(QueryManager queryManager) {
304: this .queryManager = queryManager;
305: }
306:
307: public void clean() {
308: try {
309: //clean the cache of objects
310: cacheManager.unbindAll();
311: //clean the query manager
312: queryManager.clean();
313: //clean the jorm factory
314: jormFactory.clean();
315: } catch (CacheException e) {
316: e.printStackTrace();
317: logger.log(BasicLevel.ERROR,
318: "Error while cleaning the pmf: " + e.getMessage());
319: } catch (PException e) {
320: e.printStackTrace();
321: logger.log(BasicLevel.ERROR,
322: "Error while cleaning the pmf: " + e.getMessage());
323: }
324: }
325:
326: public Personality getPersonality() {
327: return personality;
328: }
329:
330: /** Return non-configurable properties of this POManagerFactory.
331: * Properties with keys VendorName and VersionNumber are required. Other
332: * keys are optional.
333: * @return the non-configurable properties of this
334: * PersistenceManagerFactory.
335: */
336: public Properties getProperties() {
337: return connectionProperties;
338: }
339:
340: // IMPLEMENTATION OF THE PoolProvider INTERFACE //
341: //----------------------------------------------//
342:
343: /**
344: * @return the owned <code>Pool</code>
345: */
346: public Pool getPool() {
347: return managedPM;
348: }
349: }
|