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.adapter.impl;
018:
019: import java.io.IOException;
020: import java.util.ArrayList;
021: import java.util.HashMap;
022: import java.util.List;
023: import java.util.Map;
024:
025: import org.apache.avalon.framework.activity.Disposable;
026: import org.apache.avalon.framework.activity.Initializable;
027: import org.apache.avalon.framework.context.Context;
028: import org.apache.avalon.framework.context.ContextException;
029: import org.apache.avalon.framework.context.Contextualizable;
030: import org.apache.avalon.framework.service.ServiceException;
031: import org.apache.avalon.framework.service.ServiceManager;
032: import org.apache.cocoon.ProcessingException;
033: import org.apache.cocoon.components.ContextHelper;
034: import org.apache.cocoon.components.notification.Notifying;
035: import org.apache.cocoon.components.notification.NotifyingBuilder;
036: import org.apache.cocoon.components.source.SourceUtil;
037: import org.apache.cocoon.environment.ObjectModelHelper;
038: import org.apache.cocoon.portal.Constants;
039: import org.apache.cocoon.portal.PortalService;
040: import org.apache.cocoon.portal.coplet.CopletInstanceData;
041: import org.apache.cocoon.portal.event.CopletInstanceEvent;
042: import org.apache.cocoon.portal.event.EventManager;
043: import org.apache.cocoon.portal.event.Receiver;
044: import org.apache.excalibur.source.Source;
045: import org.apache.excalibur.source.SourceResolver;
046: import org.xml.sax.ContentHandler;
047: import org.xml.sax.SAXException;
048:
049: /**
050: * This is the adapter to use pipelines as coplets
051: *
052: * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
053: * @author <a href="mailto:volker.schmitt@basf-it-services.com">Volker Schmitt</a>
054: *
055: * @version CVS $Id: URICopletAdapter.java 433543 2006-08-22 06:22:54Z crossley $
056: */
057: public class URICopletAdapter extends AbstractCopletAdapter implements
058: Disposable, Receiver, Initializable, Contextualizable {
059:
060: /** The source resolver */
061: protected SourceResolver resolver;
062:
063: /** The application context */
064: protected Context context;
065:
066: /**
067: * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
068: */
069: public void contextualize(Context context) throws ContextException {
070: this .context = context;
071: }
072:
073: /**
074: * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
075: */
076: public void service(ServiceManager manager) throws ServiceException {
077: super .service(manager);
078: this .resolver = (SourceResolver) this .manager
079: .lookup(SourceResolver.ROLE);
080: }
081:
082: /**
083: * @see org.apache.cocoon.portal.coplet.adapter.impl.AbstractCopletAdapter#streamContent(org.apache.cocoon.portal.coplet.CopletInstanceData, org.xml.sax.ContentHandler)
084: */
085: public void streamContent(CopletInstanceData coplet,
086: ContentHandler contentHandler) throws SAXException {
087: final String uri = (String) coplet.getCopletData()
088: .getAttribute("uri");
089: if (uri == null) {
090: throw new SAXException("No URI for coplet data "
091: + coplet.getCopletData().getId() + " found.");
092: }
093: this .streamContent(coplet, uri, contentHandler);
094: }
095:
096: public void streamContent(final CopletInstanceData coplet,
097: final String uri, final ContentHandler contentHandler)
098: throws SAXException {
099: Source copletSource = null;
100: PortalService portalService = null;
101: try {
102: if (uri.startsWith("cocoon:")) {
103: portalService = (PortalService) this .manager
104: .lookup(PortalService.ROLE);
105:
106: Boolean handlePars = (Boolean) this .getConfiguration(
107: coplet, "handleParameters", Boolean.FALSE);
108:
109: String sourceUri = uri;
110:
111: if (handlePars.booleanValue()) {
112: List list = (List) portalService
113: .getTemporaryAttribute(URICopletAdapter.class
114: .getName());
115: if (list != null && list.contains(coplet)) {
116: // add parameters
117: if (uri.startsWith("cocoon:raw:")) {
118: sourceUri = "cocoon:" + uri.substring(11);
119: }
120: } else {
121: // remove parameters
122: if (!uri.startsWith("cocoon:raw:")) {
123: sourceUri = "cocoon:raw:"
124: + uri.substring(7);
125: }
126: }
127: }
128:
129: HashMap par = new HashMap();
130: par.put(Constants.PORTAL_NAME_KEY, portalService
131: .getPortalName());
132: par.put(Constants.COPLET_ID_KEY, coplet.getId());
133:
134: copletSource = this .resolver.resolveURI(sourceUri,
135: null, par);
136: } else {
137: copletSource = this .resolver.resolveURI(uri);
138: }
139: SourceUtil.toSAX(copletSource, contentHandler);
140: } catch (IOException ioe) {
141: throw new SAXException("IOException", ioe);
142: } catch (ProcessingException pe) {
143: throw new SAXException("ProcessingException", pe);
144: } catch (ServiceException ce) {
145: throw new SAXException("ServiceException", ce);
146: } finally {
147: this .resolver.release(copletSource);
148: this .manager.release(portalService);
149: }
150: }
151:
152: /**
153: * @see org.apache.avalon.framework.activity.Disposable#dispose()
154: */
155: public void dispose() {
156: if (this .manager != null) {
157: EventManager eventManager = null;
158: try {
159: eventManager = (EventManager) this .manager
160: .lookup(EventManager.ROLE);
161: eventManager.unsubscribe(this );
162: } catch (Exception ignore) {
163: // ignore
164: } finally {
165: this .manager.release(eventManager);
166: }
167:
168: this .manager.release(this .resolver);
169: this .resolver = null;
170: this .manager = null;
171: }
172: }
173:
174: /**
175: * @see Receiver
176: */
177: public void inform(CopletInstanceEvent event, PortalService service) {
178: List list = (List) service
179: .getTemporaryAttribute(URICopletAdapter.class.getName());
180: if (list == null) {
181: list = new ArrayList();
182: }
183: if (!list.contains(event.getTarget())) {
184: list.add(event.getTarget());
185: }
186: service.setTemporaryAttribute(URICopletAdapter.class.getName(),
187: list);
188: }
189:
190: /**
191: * @see org.apache.avalon.framework.activity.Initializable#initialize()
192: */
193: public void initialize() throws Exception {
194: EventManager eventManager = null;
195: try {
196: eventManager = (EventManager) this .manager
197: .lookup(EventManager.ROLE);
198: eventManager.subscribe(this );
199: } finally {
200: this .manager.release(eventManager);
201: }
202: }
203:
204: /**
205: * Render the error content for a coplet
206: * @param coplet The coplet instance data
207: * @param handler The content handler
208: * @param error The exception that occured
209: * @return True if the error content has been rendered, otherwise false
210: * @throws SAXException
211: */
212: protected boolean renderErrorContent(CopletInstanceData coplet,
213: ContentHandler handler, Exception error)
214: throws SAXException {
215: final String uri = (String) this .getConfiguration(coplet,
216: "error-uri");
217: if (uri != null) {
218: // TODO - if an error occured for this coplet, remember this
219: // and use directly the error-uri from now on
220:
221: if (uri.startsWith("cocoon:") && error != null) {
222: // Create a Notifying
223: NotifyingBuilder notifyingBuilder = null;
224: Notifying currentNotifying = null;
225: try {
226: notifyingBuilder = (NotifyingBuilder) this .manager
227: .lookup(NotifyingBuilder.ROLE);
228: currentNotifying = notifyingBuilder.build(this ,
229: error);
230: } catch (Exception ignore) {
231: // ignore
232: } finally {
233: this .manager.release(notifyingBuilder);
234: }
235:
236: final Map objectModel = ContextHelper
237: .getObjectModel(this .context);
238: // Add it to the object model
239: if (currentNotifying != null) {
240: objectModel
241: .put(
242: org.apache.cocoon.Constants.NOTIFYING_OBJECT,
243: currentNotifying);
244: objectModel.put(ObjectModelHelper.THROWABLE_OBJECT,
245: error);
246: }
247:
248: try {
249: this .streamContent(coplet, uri, handler);
250: } finally {
251: objectModel
252: .remove(org.apache.cocoon.Constants.NOTIFYING_OBJECT);
253: objectModel
254: .remove(ObjectModelHelper.THROWABLE_OBJECT);
255: }
256: } else {
257:
258: this .streamContent(coplet, uri, handler);
259: }
260:
261: return true;
262: }
263: return false;
264: }
265: }
|