001: /**
002: * Copyright (C) 2001-2005 France Telecom R&D
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package org.objectweb.speedo.pm.lib;
018:
019: import org.objectweb.fractal.adl.Factory;
020: import org.objectweb.fractal.adl.FactoryFactory;
021: import org.objectweb.fractal.api.Component;
022: import org.objectweb.fractal.api.Interface;
023: import org.objectweb.fractal.api.control.BindingController;
024: import org.objectweb.fractal.api.control.IllegalLifeCycleException;
025: import org.objectweb.fractal.api.control.LifeCycleController;
026: import org.objectweb.fractal.util.Fractal;
027: import org.objectweb.perseus.pool.api.PoolMatchFactory;
028: import org.objectweb.perseus.pool.api.PoolException;
029: import org.objectweb.perseus.persistence.api.ConnectionHolderFactory;
030: import org.objectweb.speedo.pm.api.POManagerInstanciatorAC;
031: import org.objectweb.speedo.pm.api.POManagerItf;
032: import org.objectweb.speedo.pm.jdo.lib.JDOPOManager;
033: import org.objectweb.speedo.workingset.api.TransactionItf;
034: import org.objectweb.speedo.workingset.lib.AbstractTransaction;
035: import org.objectweb.util.monolog.api.BasicLevel;
036: import org.objectweb.util.monolog.api.Logger;
037:
038: import java.util.HashMap;
039: import java.util.Map;
040: import java.util.Arrays;
041:
042: /**
043: * is a primitive components in charge of the POManagerItf and the TransactionItf
044: * allocation. It exports the PoolMatchFactory interface in order to be used by
045: * a Pool as Factory of pool resource. The pool resource is POManagerItf
046: * instances.
047: * It uses a ConnectionHolderFactory for allocating ConnectionHolder to the
048: * created TransactionItf components.
049: *
050: * @see org.objectweb.speedo.pm.api.POManagerItf
051: * @see org.objectweb.speedo.workingset.api.TransactionItf
052: * @see org.objectweb.perseus.persistence.api.ConnectionHolder
053: * @see org.objectweb.perseus.persistence.api.ConnectionHolderFactory
054: *
055: * @author S.Chassande-Barrioz
056: */
057: public class POManagerInstanciatorImpl implements PoolMatchFactory,
058: BindingController, LifeCycleController, POManagerInstanciatorAC {
059:
060: public final static String CONNECTION_HOLDER_FACTORY_BINDING = "connection-holder-factory";
061: public final static String COMPONENT_BINDING = "component";
062:
063: /**
064: * The factory if ConnectionHolder used at JDOTransactionItf instanciation time.
065: *
066: * @see org.objectweb.perseus.persistence.api.ConnectionHolder
067: * @see org.objectweb.perseus.persistence.api.ConnectionHolderFactory
068: */
069: private ConnectionHolderFactory chf;
070:
071: /**
072: * The current component interface.
073: */
074: private Component this C = null;
075:
076: /**
077: * The template of the POManagerItf component to instanciate
078: */
079: private Component pmT;
080:
081: /**
082: * The template of the JDOTransactionItf component to instanciate
083: */
084: private Component tT;
085:
086: /**
087: * life cycle status of the current component
088: */
089: private boolean started = false;
090:
091: private String pmTemplate;
092: private String txTemplate;
093:
094: private Logger logger;
095:
096: /**
097: * The array of common components required by a POManagerItf and JDOTransactionItf
098: * components. At each index matches a particular component ( see the
099: * XXX_COMPONENT_IDX fields).
100: *
101: * @see #PMF_COMPONENT_IDX
102: * @see #MAPPER_COMPONENT_IDX
103: * @see #JF_COMPONENT_IDX
104: * @see #PNC_COMPONENT_IDX
105: * @see #QM_COMPONENT_IDX
106: * @see #TPM_COMPONENT_IDX
107: */
108: Object[] components = new Object[6];
109:
110: private final static byte PMF_COMPONENT_IDX = 0;
111: private final static byte MAPPER_COMPONENT_IDX = PMF_COMPONENT_IDX + 1;
112: private final static byte JF_COMPONENT_IDX = MAPPER_COMPONENT_IDX + 1;
113: private final static byte PNC_COMPONENT_IDX = JF_COMPONENT_IDX + 1;
114: private final static byte QM_COMPONENT_IDX = PNC_COMPONENT_IDX + 1;
115: private final static byte TPM_COMPONENT_IDX = QM_COMPONENT_IDX + 1;
116:
117: /**
118: * The reference the composite component containing the POManagerItf and
119: * JDOTransactionItf components to instanciate.
120: */
121: Component speedoComponent = null;
122:
123: void clearComponentRef() {
124: Arrays.fill(components, null);
125: }
126:
127: /**
128: * Fills the components array with components required by a POManagerItf and
129: * JDOTransactionItf components.
130: */
131: void fetchComponentRef() throws Exception {
132: speedoComponent = Fractal.getSuperController(this C)
133: .getFcSuperComponents()[0];
134: Component[] children = Fractal.getContentController(
135: speedoComponent).getFcSubComponents();
136: for (int i = 0; i < children.length; i++) {
137: String name = Fractal.getNameController(children[i])
138: .getFcName();
139: if ("po-manager-factory".equals(name)) {
140: components[PMF_COMPONENT_IDX] = children[i]
141: .getFcInterface("po-manager-factory");
142: } else if ("mapper".equals(name)) {
143: components[MAPPER_COMPONENT_IDX] = children[i]
144: .getFcInterface("mapper");
145: components[JF_COMPONENT_IDX] = children[i]
146: .getFcInterface("jorm-factory");
147: components[PNC_COMPONENT_IDX] = children[i]
148: .getFcInterface("pname-coder");
149: } else if ("query-manager".equals(name)) {
150: components[QM_COMPONENT_IDX] = children[i]
151: .getFcInterface("query-manager");
152: } else if ("tpm".equals(name)) {
153: components[TPM_COMPONENT_IDX] = children[i]
154: .getFcInterface("transactional-persistence-manager");
155: }
156: }
157: Factory factory = FactoryFactory
158: .getFactory(FactoryFactory.FRACTAL_BACKEND);
159: Map ctxt = new HashMap();
160: ctxt.put("template", "true");
161: pmT = (Component) factory.newComponent(pmTemplate, ctxt);
162: tT = (Component) factory.newComponent(txTemplate, ctxt);
163: }
164:
165: // IMPLEMENTATION OF THE UserBindingController INTERFACE //
166: //-------------------------------------------------------//
167:
168: public String getFcState() {
169: return started ? STARTED : STOPPED;
170: }
171:
172: /**
173: * Startes the component by computing the components array.
174: */
175: public void startFc() throws IllegalLifeCycleException {
176: started = true;
177: try {
178: fetchComponentRef();
179: } catch (Exception e) {
180: if (logger != null) {
181: logger.log(BasicLevel.ERROR,
182: "Impossible to fetch inner speedo components",
183: e);
184: }
185: throw new IllegalLifeCycleException(e.getMessage());
186: }
187: }
188:
189: /**
190: * Clears the components array.
191: */
192: public void stopFc() throws IllegalLifeCycleException {
193: started = false;
194: clearComponentRef();
195: }
196:
197: // IMPLEMENTATION OF THE UserBindingController INTERFACE //
198: //-------------------------------------------------------//
199:
200: public String[] listFc() {
201: return new String[] { CONNECTION_HOLDER_FACTORY_BINDING };
202: }
203:
204: public Object lookupFc(String c) {
205: if (CONNECTION_HOLDER_FACTORY_BINDING.equals(c)) {
206: return chf;
207: } else {
208: return null;
209: }
210: }
211:
212: public void bindFc(String c, Object s) {
213: if ("logger".equals(c)) {
214: logger = (Logger) s;
215: } else if (CONNECTION_HOLDER_FACTORY_BINDING.equals(c)) {
216: chf = (ConnectionHolderFactory) s;
217: } else if (COMPONENT_BINDING.equals(c)) {
218: this C = (Component) s;
219: }
220: }
221:
222: public void unbindFc(String c) {
223: if (CONNECTION_HOLDER_FACTORY_BINDING.equals(c)) {
224: chf = null;
225: }
226: }
227:
228: // IMPLEMENTATION OF THE POManagerInstanciatorAC INTERFACE //
229: //---------------------------------------------------------//
230:
231: public String getPOManagerTemplateName() {
232: return pmTemplate;
233: }
234:
235: public void setPOManagerTemplateName(String n) {
236: pmTemplate = n;
237: }
238:
239: public String getTransactionTemplateName() {
240: return txTemplate;
241: }
242:
243: public void setTransactionTemplateName(String n) {
244: txTemplate = n;
245: }
246:
247: // IMPLEMENTATION OF THE PoolMathcFactory INTERFACE //
248: //--------------------------------------------------//
249:
250: /**
251: * Creates a new <code>PoolResource</code>.
252: * This methos is invoked by the owned <code>Pool</code>.
253: * A new JDOPOManager and a new JDOTransaction component are
254: * created, and added into the Speedo composite.
255: *
256: * @param o params used to build a new PoolResource
257: * @return the build <code>JDOPOManager</code>
258: */
259: public Object createResource(Object o) throws PoolException {
260: try {
261: //instanciate the POManagerItf
262: Component pmC = Fractal.getFactory(pmT).newFcInstance();
263: POManagerItf pm = (POManagerItf) pmC
264: .getFcInterface("po-manager");
265: Fractal.getNameController(pmC).setFcName("po-manager");
266: BindingController pmBC = Fractal.getBindingController(pmC);
267:
268: //instanciate the JDOTransactionItf
269: Component tC = Fractal.getFactory(tT).newFcInstance();
270: Fractal.getNameController(tC).setFcName("transaction");
271: TransactionItf t = (TransactionItf) tC
272: .getFcInterface("transaction");
273: BindingController tBC = Fractal.getBindingController(tC);
274:
275: //Add the new components into the Speedo composite
276: Fractal.getContentController(speedoComponent)
277: .addFcSubComponent(pmC);
278: Fractal.getContentController(speedoComponent)
279: .addFcSubComponent(tC);
280:
281: //add bindings on the po manager
282: pmBC.bindFc(JDOPOManager.JORM_FACTORY_BINDING,
283: components[JF_COMPONENT_IDX]);
284: pmBC.bindFc(JDOPOManager.PNAME_CODER_BINDING,
285: components[PNC_COMPONENT_IDX]);
286: pmBC.bindFc(JDOPOManager.PO_MANAGER_FACTORY_BINDING,
287: components[PMF_COMPONENT_IDX]);
288: pmBC.bindFc(JDOPOManager.QUERY_MANAGER_BINDING,
289: components[QM_COMPONENT_IDX]);
290: pmBC
291: .bindFc(
292: JDOPOManager.TRANSACTIONAL_PERSISTENCE_MANAGER_BINDING,
293: components[TPM_COMPONENT_IDX]);
294: pmBC.bindFc(JDOPOManager.TRANSACTION_BINDING, t);
295:
296: //add bindings on the transaction
297: tBC.bindFc(AbstractTransaction.PO_MANAGER_BINDING, pm);
298: tBC
299: .bindFc(
300: AbstractTransaction.TRANSACTIONAL_PERSISTENCE_MANAGER_BINDING,
301: components[TPM_COMPONENT_IDX]);
302: tBC.bindFc(AbstractTransaction.MAPPER_BINDING,
303: components[MAPPER_COMPONENT_IDX]);
304:
305: //Add a ConenctionHolder to the transaction
306: t.setConnectionHolder(chf.createConnectionHolder());
307:
308: //start components
309: Fractal.getLifeCycleController(pmC).startFc();
310: Fractal.getLifeCycleController(tC).startFc();
311:
312: return pm;
313: } catch (Exception e) {
314: PoolException pe = new PoolException(
315: "Error during the allocation of a new POManagerItf and its WorkingSet",
316: e);
317: logger.log(BasicLevel.ERROR, pe.getMessage() + ": "
318: + e.getMessage(), e);
319: throw pe;
320: }
321: }
322:
323: public boolean matchResource(Object resource, Object o) {
324: return true;
325: }
326:
327: /**
328: * It removes the POManagerItf and the JDOTransactionItf components from the
329: * Speedo composite.
330: * @param resource is the POManagerItf to destroy.
331: */
332: public void destroyResource(Object resource) {
333: try {
334: //fetch the PM component
335: Component pmC = ((Interface) resource).getFcItfOwner();
336: BindingController pmBC = Fractal.getBindingController(pmC);
337:
338: //fetch the Tx component
339: Component tC = ((Interface) pmBC
340: .lookupFc(AbstractPOManager.TRANSACTION_BINDING))
341: .getFcItfOwner();
342: BindingController tBC = Fractal.getBindingController(tC);
343:
344: //Stop compoenents
345: Fractal.getLifeCycleController(pmC).stopFc();
346: Fractal.getLifeCycleController(tC).stopFc();
347:
348: //remove bindings of the PM component
349: pmBC.unbindFc(AbstractPOManager.JORM_FACTORY_BINDING);
350: pmBC.unbindFc(AbstractPOManager.PNAME_CODER_BINDING);
351: pmBC.unbindFc(AbstractPOManager.PO_MANAGER_FACTORY_BINDING);
352: pmBC.unbindFc(AbstractPOManager.QUERY_MANAGER_BINDING);
353: pmBC
354: .unbindFc(AbstractPOManager.TRANSACTIONAL_PERSISTENCE_MANAGER_BINDING);
355: pmBC.unbindFc(AbstractPOManager.TRANSACTION_BINDING);
356:
357: //remove bindings of the Tx component
358: tBC.unbindFc(AbstractTransaction.PO_MANAGER_BINDING);
359: tBC
360: .unbindFc(AbstractTransaction.TRANSACTIONAL_PERSISTENCE_MANAGER_BINDING);
361: tBC.unbindFc(AbstractTransaction.MAPPER_BINDING);
362:
363: //remove both components from the composite
364: //TODO: find a way to remove sub components without stopping Speedo !!!
365: //Fractal.getContentController(speedoComponent).removeFcSubComponent(pmC);
366: //Fractal.getContentController(speedoComponent).removeFcSubComponent(tC);
367: } catch (Exception e) {
368: if (logger != null) {
369: logger
370: .log(
371: BasicLevel.WARN,
372: "Error during the destroying of a POManagerItf",
373: e);
374: }
375: }
376: }
377:
378: }
|