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:
018: package org.apache.cocoon.slop.generation;
019:
020: import java.io.IOException;
021: import java.io.InputStreamReader;
022: import java.io.LineNumberReader;
023: import java.io.Serializable;
024: import java.util.Map;
025:
026: import org.apache.avalon.framework.parameters.Parameters;
027: import org.apache.cocoon.ProcessingException;
028: import org.apache.cocoon.caching.CacheableProcessingComponent;
029: import org.apache.cocoon.environment.SourceResolver;
030: import org.apache.cocoon.generation.ServiceableGenerator;
031: import org.apache.cocoon.slop.interfaces.SlopParser;
032: import org.apache.cocoon.slop.parsing.SimpleSlopParser;
033: import org.apache.excalibur.source.Source;
034: import org.apache.excalibur.source.SourceException;
035: import org.apache.excalibur.source.SourceValidity;
036: import org.xml.sax.SAXException;
037: import org.xml.sax.helpers.LocatorImpl;
038:
039: /**
040: * SlopGenerator: Simple Line-Oriented Parsing of text files.
041: * General code structure lifted from the Chaperon TextGenerator - thanks Stephan!
042: *
043: * @author <a href="mailto:bdelacretaz@apache.org">Bertrand Delacretaz</a>
044: * @version CVS $Id: SlopGenerator.java 433543 2006-08-22 06:22:54Z crossley $
045: */
046:
047: public class SlopGenerator extends ServiceableGenerator implements
048: CacheableProcessingComponent {
049:
050: private Source inputSource = null;
051: private String encoding = null;
052: private SlopParser parser = null;
053: private boolean preserveSpace = false;
054: private String validTagnameChars = null;
055:
056: /**
057: * Recycle this component.
058: * All instance variables are set to <code>null</code>.
059: */
060: public void recycle() {
061: if (inputSource != null) {
062: super .resolver.release(inputSource);
063: }
064: inputSource = null;
065: encoding = null;
066: preserveSpace = false;
067: parser = null;
068: validTagnameChars = null;
069:
070: super .recycle();
071: }
072:
073: /**
074: * Set the SourceResolver, objectModel Map, the source and sitemap
075: * Parameters used to process the request.
076: *
077: * @param resolver Source resolver
078: * @param objectmodel Object model
079: * @param src Source
080: * @param parameters Parameters
081: *
082: * @throws java.io.IOException
083: * @throws org.apache.cocoon.ProcessingException
084: * @throws org.xml.sax.SAXException
085: */
086: public void setup(SourceResolver resolver, Map objectmodel,
087: String src, Parameters parameters)
088: throws ProcessingException, SAXException, IOException {
089: super .setup(resolver, objectmodel, src, parameters);
090: try {
091: encoding = parameters.getParameter("encoding", null);
092: preserveSpace = parameters.getParameterAsBoolean(
093: "preserve-space", false);
094: validTagnameChars = parameters.getParameter(
095: "valid-tagname-chars", null);
096: inputSource = resolver.resolveURI(src);
097:
098: final SimpleSlopParser ssp = new SimpleSlopParser();
099: parser = ssp;
100: ssp.setPreserveWhitespace(preserveSpace);
101: ssp.setValidTagnameChars(validTagnameChars);
102: } catch (SourceException se) {
103: throw new ProcessingException("Error during resolving of '"
104: + src + "'.", se);
105: }
106: }
107:
108: /**
109: * Generate the unique key.
110: * This key must be unique inside the space of this component.
111: *
112: * @return The generated key hashes the src
113: */
114: public Serializable getKey() {
115: return inputSource.getURI();
116: }
117:
118: /**
119: * Generate the validity object.
120: *
121: * @return The generated validity object or <code>null</code> if the
122: * component is currently not cacheable.
123: */
124: public SourceValidity getValidity() {
125: return this .inputSource.getValidity();
126: }
127:
128: /**
129: * Generate XML data.
130: *
131: * @throws java.io.IOException
132: * @throws org.apache.cocoon.ProcessingException
133: * @throws org.xml.sax.SAXException
134: */
135: public void generate() throws IOException, SAXException,
136: ProcessingException {
137:
138: // access input data, using specified encoding if any
139: InputStreamReader in = null;
140:
141: try {
142: if (this .inputSource.getInputStream() == null) {
143: throw new ProcessingException("Source '"
144: + this .inputSource.getURI() + "' not found");
145: }
146:
147: if (encoding != null) {
148: in = new InputStreamReader(this .inputSource
149: .getInputStream(), encoding);
150: } else {
151: in = new InputStreamReader(this .inputSource
152: .getInputStream());
153: }
154: } catch (SourceException se) {
155: throw new ProcessingException("Error during resolving of '"
156: + this .source + "'.", se);
157: }
158:
159: // setup a Locator in case parser detects input errors
160: final LocatorImpl locator = new LocatorImpl();
161:
162: locator.setSystemId(this .inputSource.getURI());
163: locator.setLineNumber(1);
164: locator.setColumnNumber(1);
165:
166: contentHandler.setDocumentLocator(locator);
167:
168: // start parsing, read and process all input lines
169: parser.startDocument(contentHandler);
170:
171: LineNumberReader reader = new LineNumberReader(in);
172: String line, newline = null;
173:
174: while (true) {
175: if (newline == null) {
176: line = reader.readLine();
177: } else {
178: line = newline;
179: }
180:
181: if (line == null) {
182: break;
183: }
184:
185: newline = reader.readLine();
186:
187: locator.setLineNumber(reader.getLineNumber());
188: locator.setColumnNumber(1);
189: parser.processLine(line);
190:
191: if (newline == null) {
192: break;
193: }
194: }
195:
196: // done parsing
197: parser.endDocument();
198: }
199: }
|