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.transformation;
018:
019: import java.io.ByteArrayInputStream;
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.Serializable;
023: import java.util.Map;
024:
025: import org.apache.avalon.framework.parameters.Parameters;
026: import org.apache.avalon.framework.service.ServiceException;
027: import org.apache.cocoon.ProcessingException;
028: import org.apache.cocoon.caching.CacheableProcessingComponent;
029: import org.apache.cocoon.components.sax.XMLDeserializer;
030: import org.apache.cocoon.components.sax.XMLSerializer;
031: import org.apache.cocoon.environment.SourceResolver;
032: import org.apache.cocoon.transformation.AbstractSAXTransformer;
033: import org.apache.cocoon.xml.IncludeXMLConsumer;
034: import org.apache.cocoon.xml.XMLConsumer;
035: import org.apache.excalibur.source.SourceValidity;
036: import org.apache.excalibur.source.impl.validity.NOPValidity;
037: import org.apache.excalibur.xmlizer.XMLizer;
038: import org.xml.sax.Attributes;
039: import org.xml.sax.SAXException;
040:
041: /**
042: * This transformer records the content of all description elements
043: * and tries to interpret them as valid XML.
044: * It's actually a quick hack...
045: *
046: * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
047: * @version CVS $Id: RSSTransformer.java 433543 2006-08-22 06:22:54Z crossley $
048: */
049: public final class RSSTransformer extends AbstractSAXTransformer
050: implements CacheableProcessingComponent {
051:
052: /** The xmlizer for converting html to xml */
053: protected XMLizer xmlizer;
054:
055: /** The xml deserializer */
056: protected XMLDeserializer deserializer;
057:
058: /** The filter */
059: protected XMLConsumer filter;
060:
061: /**
062: * receive notification of start element event.
063: **/
064: public void startElement(String uri, String name, String raw,
065: Attributes attributes) throws SAXException {
066: super .startElement(uri, name, raw, attributes);
067: if ("description".equals(name)) {
068: this .startTextRecording();
069: }
070: }
071:
072: /**
073: * receive notification of end element event.
074: */
075: public void endElement(String uri, String name, String raw)
076: throws SAXException {
077: if ("description".equals(name)) {
078: final String text = this .endTextRecording();
079: final String html = "<html><body>" + text
080: + "</body></html>";
081:
082: Object parsed = null;
083: XMLSerializer serializer = null;
084: try {
085: serializer = (XMLSerializer) this .manager
086: .lookup(XMLSerializer.ROLE);
087: InputStream inputStream = new ByteArrayInputStream(html
088: .getBytes());
089: this .xmlizer.toSAX(inputStream, "text/html", null,
090: serializer);
091: // if no exception occurs, everything is fine!
092: parsed = serializer.getSAXFragment();
093: } catch (Exception ignore) {
094: // just ignore all exceptions
095: } finally {
096: this .manager.release(serializer);
097: }
098: if (parsed != null) {
099: this .deserializer.setConsumer(this .filter);
100: this .deserializer.deserialize(parsed);
101: } else {
102: this .sendTextEvent(text);
103: }
104: }
105: super .endElement(uri, name, raw);
106: }
107:
108: /* (non-Javadoc)
109: * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
110: */
111: public void recycle() {
112: this .manager.release(this .xmlizer);
113: this .manager.release(this .deserializer);
114: this .xmlizer = null;
115: this .deserializer = null;
116: this .filter = null;
117: super .recycle();
118: }
119:
120: /* (non-Javadoc)
121: * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver, java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
122: */
123: public void setup(SourceResolver resolver, Map objectModel,
124: String src, Parameters par) throws ProcessingException,
125: SAXException, IOException {
126: super .setup(resolver, objectModel, src, par);
127: try {
128: this .xmlizer = (XMLizer) this .manager.lookup(XMLizer.ROLE);
129: this .deserializer = (XMLDeserializer) this .manager
130: .lookup(XMLDeserializer.ROLE);
131: } catch (ServiceException ce) {
132: throw new ProcessingException(
133: "Unable to lookup component.", ce);
134: }
135: }
136:
137: static class HTMLFilter extends IncludeXMLConsumer {
138:
139: int bodyCount = 0;
140:
141: public HTMLFilter(XMLConsumer consumer) {
142: super (consumer);
143: }
144:
145: public void startElement(String uri, String local,
146: String qName, Attributes attr) throws SAXException {
147: if (bodyCount > 0) {
148: super .startElement(uri, local, qName, attr);
149: }
150: if ("body".equalsIgnoreCase(local)) {
151: bodyCount++;
152: }
153: }
154:
155: public void endElement(String uri, String local, String qName)
156: throws SAXException {
157: if ("body".equalsIgnoreCase(local)) {
158: bodyCount--;
159: }
160: if (bodyCount > 0) {
161: super .endElement(uri, local, qName);
162: }
163: }
164:
165: }
166:
167: /* (non-Javadoc)
168: * @see org.apache.cocoon.transformation.AbstractSAXTransformer#setupTransforming()
169: */
170: public void setupTransforming() throws IOException,
171: ProcessingException, SAXException {
172: super .setupTransforming();
173: this .filter = new HTMLFilter(this .xmlConsumer);
174: }
175:
176: /* (non-Javadoc)
177: * @see org.apache.cocoon.caching.CacheableProcessingComponent#getKey()
178: */
179: public Serializable getKey() {
180: return "1";
181: }
182:
183: /* (non-Javadoc)
184: * @see org.apache.cocoon.caching.CacheableProcessingComponent#getValidity()
185: */
186: public SourceValidity getValidity() {
187: return NOPValidity.SHARED_INSTANCE;
188: }
189:
190: }
|