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.generation;
018:
019: import java.io.IOException;
020: import java.io.OutputStream;
021: import java.io.PipedInputStream;
022: import java.io.PipedOutputStream;
023: import java.util.Enumeration;
024:
025: import javax.servlet.ServletConfig;
026: import javax.servlet.ServletContext;
027: import javax.servlet.ServletException;
028: import javax.servlet.http.HttpServletRequest;
029: import javax.servlet.http.HttpServletResponse;
030:
031: import org.apache.avalon.framework.component.Component;
032: import org.apache.avalon.framework.CascadingRuntimeException;
033: import org.apache.avalon.framework.logger.Logger;
034:
035: import org.apache.cocoon.ProcessingException;
036: import org.apache.cocoon.environment.http.HttpEnvironment;
037:
038: import org.apache.excalibur.source.Source;
039: import org.apache.excalibur.xml.sax.SAXParser;
040:
041: import org.xml.sax.InputSource;
042: import org.xml.sax.SAXException;
043:
044: /**
045: * Allows PHP to be used as a generator. Builds upon the PHP servlet
046: * functionallity - overrides the output method in order to pipe the
047: * results into SAX events.
048: *
049: * @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a>
050: * @version CVS $Id: PhpGenerator.java 433543 2006-08-22 06:22:54Z crossley $
051: */
052: public class PhpGenerator extends ServletGenerator {
053:
054: /**
055: * Stub implementation of Servlet Config
056: */
057: class config implements ServletConfig {
058: ServletContext c;
059:
060: public config(ServletContext c) {
061: this .c = c;
062: }
063:
064: public String getServletName() {
065: return "PhpGenerator";
066: }
067:
068: public Enumeration getInitParameterNames() {
069: return c.getInitParameterNames();
070: }
071:
072: public ServletContext getServletContext() {
073: return c;
074: }
075:
076: public String getInitParameter(String name) {
077: return null;
078: }
079: }
080:
081: /**
082: * Subclass the PHP servlet implementation, overriding the method
083: * that produces the output.
084: */
085: public class PhpServlet extends net.php.servlet implements Runnable {
086:
087: String input;
088: OutputStream output;
089: HttpServletRequest request;
090: HttpServletResponse response;
091: ServletException exception = null;
092: Logger logger;
093:
094: protected PhpServlet(Logger logger) {
095: this .logger = logger;
096: }
097:
098: public void setInput(String input) {
099: this .input = input;
100: }
101:
102: public void setOutput(OutputStream output) {
103: this .output = output;
104: }
105:
106: public void setRequest(HttpServletRequest request) {
107: this .request = request;
108: }
109:
110: public void setResponse(HttpServletResponse response) {
111: this .response = response;
112: }
113:
114: public void write(String data) {
115: try {
116: output.write(data.getBytes());
117: } catch (IOException e) {
118: logger.debug("PhpGenerator.write()", e);
119: throw new CascadingRuntimeException(
120: "PhpGenerator.write()", e);
121: }
122: }
123:
124: /******************************************************************/
125: /* runnable interface */
126: /******************************************************************/
127:
128: public void run() {
129: try {
130: service(request, response, input);
131: } catch (ServletException e) {
132: logger.error("PhpGenerator.run()", e);
133: this .exception = e;
134: }
135:
136: try {
137: output.close();
138: } catch (IOException e) {
139: logger.error("PhpGenerator.run():SHOULD NEVER HAPPEN",
140: e);
141: // should never happen
142: }
143: }
144:
145: }
146:
147: /**
148: * Generate XML data from PHP.
149: */
150: public void generate() throws IOException, SAXException,
151: ProcessingException {
152:
153: // ensure that we are running in a servlet environment
154: HttpServletResponse httpResponse = (HttpServletResponse) this .objectModel
155: .get(HttpEnvironment.HTTP_RESPONSE_OBJECT);
156: HttpServletRequest httpRequest = (HttpServletRequest) this .objectModel
157: .get(HttpEnvironment.HTTP_REQUEST_OBJECT);
158: if (httpResponse == null || httpRequest == null) {
159: throw new ProcessingException(
160: "HttpServletRequest or HttpServletResponse object not available");
161: }
162:
163: // ensure that we are serving a file...
164: Source inputSource = null;
165: SAXParser parser = null;
166: try {
167: inputSource = this .resolver.resolveURI(this .source);
168: String systemId = inputSource.getURI();
169: if (!systemId.startsWith("file:/"))
170: throw new IOException("protocol not supported: "
171: + systemId);
172:
173: // construct both ends of the pipe
174: PipedInputStream input = new PipedInputStream();
175:
176: // start PHP producing results into the pipe
177: PhpServlet php = new PhpServlet(getLogger());
178: php.init(new config((ServletContext) this .objectModel
179: .get(HttpEnvironment.HTTP_SERVLET_CONTEXT)));
180: php.setInput(systemId.substring(6));
181: php.setOutput(new PipedOutputStream(input));
182: php.setRequest(httpRequest);
183: php.setResponse(httpResponse);
184: new Thread(php).start();
185:
186: // pipe the results into the parser
187: parser = (SAXParser) this .manager.lookup(SAXParser.ROLE);
188: parser.parse(new InputSource(input), this .xmlConsumer);
189:
190: // clean up
191: php.destroy();
192: } catch (IOException e) {
193: throw e;
194: } catch (Exception e) {
195: throw new ProcessingException(e.toString(), e);
196: } finally {
197: this .resolver.release(inputSource);
198: this .manager.release((Component) parser);
199: }
200: }
201: }
|