001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.portal.coplet.impl;
018:
019: import java.util.ArrayList;
020: import java.util.HashMap;
021: import java.util.List;
022: import java.util.Map;
023:
024: import org.apache.avalon.framework.activity.Disposable;
025: import org.apache.avalon.framework.component.Component;
026: import org.apache.avalon.framework.configuration.Configurable;
027: import org.apache.avalon.framework.configuration.Configuration;
028: import org.apache.avalon.framework.configuration.ConfigurationException;
029: import org.apache.avalon.framework.logger.AbstractLogEnabled;
030: import org.apache.avalon.framework.service.ServiceException;
031: import org.apache.avalon.framework.service.ServiceManager;
032: import org.apache.avalon.framework.service.ServiceSelector;
033: import org.apache.avalon.framework.service.Serviceable;
034: import org.apache.avalon.framework.thread.ThreadSafe;
035: import org.apache.cocoon.ProcessingException;
036: import org.apache.cocoon.portal.PortalService;
037: import org.apache.cocoon.portal.aspect.AspectDataHandler;
038: import org.apache.cocoon.portal.aspect.AspectDataStore;
039: import org.apache.cocoon.portal.aspect.AspectDescription;
040: import org.apache.cocoon.portal.aspect.impl.DefaultAspectDataHandler;
041: import org.apache.cocoon.portal.aspect.impl.DefaultAspectDescription;
042: import org.apache.cocoon.portal.coplet.CopletData;
043: import org.apache.cocoon.portal.coplet.CopletFactory;
044: import org.apache.cocoon.portal.coplet.CopletInstanceData;
045: import org.apache.cocoon.portal.coplet.adapter.CopletAdapter;
046:
047: /**
048: * This factory is for creating and managing coplet objects
049: *
050: * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
051: *
052: * @version CVS $Id: DefaultCopletFactory.java 433543 2006-08-22 06:22:54Z crossley $
053: */
054: public class DefaultCopletFactory extends AbstractLogEnabled implements
055: Component, ThreadSafe, CopletFactory, Serviceable, Disposable,
056: Configurable {
057:
058: protected ServiceManager manager;
059:
060: protected Map coplets = new HashMap();
061:
062: protected List descriptions = new ArrayList();
063:
064: protected ServiceSelector storeSelector;
065:
066: protected static long idCounter = System.currentTimeMillis();
067:
068: /* (non-Javadoc)
069: * @see org.apache.cocoon.portal.coplet.CopletFactory#prepare(org.apache.cocoon.portal.coplet.CopletData)
070: */
071: public void prepare(CopletData copletData)
072: throws ProcessingException {
073: if (copletData != null) {
074:
075: final String copletName = copletData.getName();
076: if (copletName == null) {
077: throw new ProcessingException("CopletData "
078: + copletData.getId()
079: + " has no associated name.");
080: }
081: Object[] o = (Object[]) this .coplets.get(copletName);
082:
083: if (o == null) {
084: throw new ProcessingException(
085: "CopletDescription with name " + copletName
086: + " not found.");
087: }
088: DefaultCopletDescription copletDescription = (DefaultCopletDescription) o[0];
089:
090: copletData.setDescription(copletDescription);
091: copletData.setAspectDataHandler((AspectDataHandler) o[1]);
092:
093: }
094: }
095:
096: /* (non-Javadoc)
097: * @see org.apache.cocoon.portal.coplet.CopletFactory#prepare(org.apache.cocoon.portal.coplet.CopletInstanceData)
098: */
099: public void prepare(CopletInstanceData copletInstanceData)
100: throws ProcessingException {
101: if (copletInstanceData != null) {
102:
103: final String copletName = copletInstanceData.getName();
104: if (copletName == null) {
105: throw new ProcessingException("CopletInstanceData "
106: + copletInstanceData.getId()
107: + " has no associated name.");
108: }
109: Object[] o = (Object[]) this .coplets.get(copletName);
110:
111: if (o == null) {
112: throw new ProcessingException(
113: "CopletDescription with name " + copletName
114: + " not found.");
115: }
116: DefaultCopletDescription copletDescription = (DefaultCopletDescription) o[0];
117:
118: copletInstanceData.setDescription(copletDescription);
119: copletInstanceData
120: .setAspectDataHandler((AspectDataHandler) o[2]);
121:
122: }
123: }
124:
125: /* (non-Javadoc)
126: * @see org.apache.cocoon.portal.coplet.CopletFactory#newInstance(org.apache.cocoon.portal.coplet.CopletData)
127: */
128: public CopletInstanceData newInstance(CopletData copletData)
129: throws ProcessingException {
130: String name = copletData.getName();
131: Object[] o = (Object[]) this .coplets.get(name);
132:
133: if (o == null) {
134: throw new ProcessingException(
135: "CopletDescription with name " + name
136: + " not found.");
137: }
138: DefaultCopletDescription copletDescription = (DefaultCopletDescription) o[0];
139:
140: CopletInstanceData instance = new CopletInstanceData();
141:
142: String id = null;
143: if (copletDescription.createId()) {
144: synchronized (this ) {
145: id = copletData.getId() + '_' + idCounter;
146: idCounter += 1;
147: }
148: }
149: instance.initialize(name, id);
150:
151: instance.setDescription(copletDescription);
152: instance.setAspectDataHandler((AspectDataHandler) o[2]);
153: instance.setCopletData(copletData);
154:
155: // now lookup the adapter
156: final String adapterName = copletData.getCopletBaseData()
157: .getCopletAdapterName();
158: CopletAdapter adapter = null;
159: ServiceSelector adapterSelector = null;
160: try {
161: adapterSelector = (ServiceSelector) this .manager
162: .lookup(CopletAdapter.ROLE + "Selector");
163: adapter = (CopletAdapter) adapterSelector
164: .select(adapterName);
165: adapter.init(instance);
166: adapter.login(instance);
167: } catch (ServiceException ce) {
168: throw new ProcessingException(
169: "Unable to lookup coplet adapter selector or adaptor.",
170: ce);
171: } finally {
172: if (adapterSelector != null) {
173: adapterSelector.release(adapter);
174: }
175: this .manager.release(adapterSelector);
176: }
177:
178: PortalService service = null;
179: try {
180: service = (PortalService) this .manager
181: .lookup(PortalService.ROLE);
182: service.getComponentManager().getProfileManager().register(
183: instance);
184: } catch (ServiceException ce) {
185: throw new ProcessingException(
186: "Unable to lookup profile manager.", ce);
187: } finally {
188: this .manager.release(service);
189: }
190: return instance;
191: }
192:
193: /* (non-Javadoc)
194: * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
195: */
196: public void service(ServiceManager manager) throws ServiceException {
197: this .manager = manager;
198: this .storeSelector = (ServiceSelector) this .manager
199: .lookup(AspectDataStore.ROLE + "Selector");
200: }
201:
202: /* (non-Javadoc)
203: * @see org.apache.avalon.framework.activity.Disposable#dispose()
204: */
205: public void dispose() {
206: if (this .manager != null) {
207: this .manager.release(this .storeSelector);
208: this .storeSelector = null;
209: this .manager = null;
210: }
211: }
212:
213: /* (non-Javadoc)
214: * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
215: */
216: public void configure(Configuration configuration)
217: throws ConfigurationException {
218: final Configuration[] copletsConf = configuration.getChild(
219: "coplets").getChildren("coplet");
220: if (copletsConf != null) {
221: for (int i = 0; i < copletsConf.length; i++) {
222: DefaultCopletDescription desc = new DefaultCopletDescription();
223: DefaultCopletDescription instanceDesc = new DefaultCopletDescription();
224: final String name = copletsConf[i].getAttribute("name");
225:
226: // unique test
227: if (this .coplets.get(name) != null) {
228: throw new ConfigurationException(
229: "Coplet name must be unique. Double definition for "
230: + name);
231: }
232: desc.setName(copletsConf[i].getAttribute("name"));
233: instanceDesc.setName(copletsConf[i]
234: .getAttribute("name"));
235: instanceDesc.setCreateId(copletsConf[i]
236: .getAttributeAsBoolean("create-id", true));
237:
238: // and now the aspects
239: Configuration[] aspectsConf = copletsConf[i].getChild(
240: "coplet-data-aspects").getChildren("aspect");
241: if (aspectsConf != null) {
242: for (int m = 0; m < aspectsConf.length; m++) {
243: AspectDescription adesc = DefaultAspectDescription
244: .newInstance(aspectsConf[m]);
245: desc.addAspectDescription(adesc);
246: }
247: }
248:
249: // and now the aspects of the instances
250: aspectsConf = copletsConf[i].getChild(
251: "coplet-instance-data-aspects").getChildren(
252: "aspect");
253: if (aspectsConf != null) {
254: for (int m = 0; m < aspectsConf.length; m++) {
255: AspectDescription adesc = DefaultAspectDescription
256: .newInstance(aspectsConf[m]);
257: instanceDesc.addAspectDescription(adesc);
258: }
259: }
260:
261: DefaultAspectDataHandler handler = new DefaultAspectDataHandler(
262: desc, this .storeSelector);
263: DefaultAspectDataHandler instanceHandler = new DefaultAspectDataHandler(
264: instanceDesc, this .storeSelector);
265: this .coplets.put(desc.getName(), new Object[] { desc,
266: handler, instanceHandler });
267: this .descriptions.add(desc);
268: }
269: }
270: }
271:
272: /* (non-Javadoc)
273: * @see org.apache.cocoon.portal.coplet.CopletFactory#remove(org.apache.cocoon.portal.coplet.CopletInstanceData)
274: */
275: public void remove(CopletInstanceData copletInstanceData)
276: throws ProcessingException {
277: if (copletInstanceData != null) {
278: // now lookup the adapter
279: final String adapterName = copletInstanceData
280: .getCopletData().getCopletBaseData()
281: .getCopletAdapterName();
282: CopletAdapter adapter = null;
283: ServiceSelector adapterSelector = null;
284: try {
285: adapterSelector = (ServiceSelector) this .manager
286: .lookup(CopletAdapter.ROLE + "Selector");
287: adapter = (CopletAdapter) adapterSelector
288: .select(adapterName);
289: adapter.logout(copletInstanceData);
290: adapter.destroy(copletInstanceData);
291: } catch (ServiceException ce) {
292: throw new ProcessingException(
293: "Unable to lookup coplet adapter selector or adaptor.",
294: ce);
295: } finally {
296: if (adapterSelector != null) {
297: adapterSelector.release(adapter);
298: }
299: this .manager.release(adapterSelector);
300: }
301:
302: PortalService service = null;
303: try {
304: service = (PortalService) this .manager
305: .lookup(PortalService.ROLE);
306: service.getComponentManager().getProfileManager()
307: .unregister(copletInstanceData);
308: } catch (ServiceException ce) {
309: throw new ProcessingException(
310: "Unable to lookup portal service.", ce);
311: } finally {
312: this.manager.release(service);
313: }
314: }
315: }
316:
317: }
|