blob: 581098db3f8b9ac923982f313b226561a79293f1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon.reading;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.components.jsp.JSPEngine;
import org.apache.cocoon.environment.http.HttpEnvironment;
import org.apache.excalibur.source.Source;
/**
* The <code>JSPReader</code> component is used to serve Servlet and JSP page
* output data in a sitemap pipeline.
*
* @author <a href="mailto:kpiroumian@flagship.ru">Konstantin Piroumian</a>
* @version CVS $Id$
*/
public class JSPReader extends ServiceableReader implements Configurable {
private static final int DEFAULT_BUFFER_SIZE = 8192;
// buffer size for IO
private int bufferSize;
// output encoding
private String outputEncoding;
public void configure(Configuration conf) throws ConfigurationException {
bufferSize = conf.getChild("buffer-size").getValueAsInteger(DEFAULT_BUFFER_SIZE);
outputEncoding = conf.getChild("output-encoding").getValue(null);
}
/**
* Generates the output from JSPEngine.
*/
public void generate() throws IOException, ProcessingException {
if (this.source == null) {
throw new ProcessingException("JSPReader: source JSP is not specified");
}
HttpServletResponse servletResponse =
(HttpServletResponse) super.objectModel.get(HttpEnvironment.HTTP_RESPONSE_OBJECT);
HttpServletRequest servletRequest =
(HttpServletRequest) super.objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);
ServletContext servletContext =
(ServletContext) super.objectModel.get(HttpEnvironment.HTTP_SERVLET_CONTEXT);
// ensure that we are running in a servlet environment
if (servletResponse == null || servletRequest == null || servletContext == null) {
throw new ProcessingException("JSPReader can only be used from within a Servlet environment.");
}
JSPEngine engine = null;
Source inputSource = null;
Source contextSource = null;
try {
inputSource = this.resolver.resolveURI(this.source);
contextSource = this.resolver.resolveURI("context:/");
String inputSourceURI = inputSource.getURI();
String contextSourceURI = contextSource.getURI();
if (!inputSourceURI.startsWith(contextSourceURI)) {
throw new ProcessingException("You must not reference a file "
+ "outside of the servlet context at " + contextSourceURI + ".");
}
String url = inputSourceURI.substring(contextSourceURI.length());
if (url.charAt(0) != '/') {
url = "/" + url;
}
if (getLogger().isDebugEnabled()) {
getLogger().debug("JSPReader executing:" + url);
}
engine = (JSPEngine) super.manager.lookup(JSPEngine.ROLE);
byte[] bytes = engine.executeJSP(url, servletRequest, servletResponse, servletContext);
if (this.outputEncoding != null) {
recodeResult (bytes, this.outputEncoding);
} else {
out.write(bytes);
out.flush();
}
bytes = null;
} catch (ServletException e) {
throw new ProcessingException("ServletException while executing JSPEngine", e);
} catch (IOException e) {
throw new ProcessingException("IOException JSPReader.generate()", e);
} catch (ProcessingException e) {
throw e;
} catch (Exception e) {
throw new ProcessingException("Exception JSPReader.generate()", e);
} finally {
super.manager.release(engine);
this.resolver.release(inputSource);
this.resolver.release(contextSource);
}
}
private void recodeResult(byte[] bytes, String encoding) throws IOException {
char[] buffer = new char[this.bufferSize];
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
// UTF-8 is the default encoding/contract of the JSPEngine
Reader reader = new InputStreamReader(bais, "UTF-8");
Writer writer = new OutputStreamWriter(out, encoding);
int length = -1;
while ((length = reader.read(buffer)) > -1) {
writer.write(buffer, 0, length);
}
writer.flush();
}
}