blob: 1715920baa9a42b2b710d86f3c18fd2c02a14995 [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.taglibs.rdc;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.jar.JarFile;
import java.util.jar.JarEntry;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* <p>GrammarServlet serves out grammars from the RDC jar.</p>
* @version 1.0
*/
public class GrammarServlet
extends HttpServlet {
//// Constants
// Serial Version UID
private static final long serialVersionUID = 1L;
// Init params and default values
private static final String INIT_PARAM_GRAM_DIR = "grammarDirectory";
private static final String DEFAULT_GRAM_DIR = ".grammar";
private static final String INIT_PARAM_JAR = "jar";
private static final String DEFAULT_JAR = "/WEB-INF/lib/taglibs-rdc.jar";
// Mimes and extensions
private static final String MIME_JAVASCRIPT = "application/x-javascript";
private static final String EXT_JAVASCRIPT = "js";
private static final String MIME_SRGS_GRAM = "application/srgs+xml";
// Error messages (to be i18n'zed)
private static final String ERR_NO_SUCH_ENTRY = "Could not locate jar " +
"entry: \"{0}\" in jar: \"{1}\"";
private static final String ERR_NO_INPUT_STREAM = "Could not obtain " +
"input stream from located Jar entry: \"{0}\" in jar: \"{1}\"";
private static final String ERR_NO_PERMISSION = "Do not have " +
"permission to access: \"{0}\"";
// Logging
private static Log log = LogFactory.getLog(GrammarServlet.class);
/* Records name of the jar from which we extract the grammar */
private String jar;
/* Name of directory within the jar that holds grammar files */
private String grammarDirectory;
/**
* This method is called once by the container when the servlet is
* initialized, before any requests are delivered to the servlet.
*
* GrammarServlet uses init params jar and grammarDirectory
* These params are recorded in member variables.
* if no init params are specified, we use some reasonable defaults.
*/
public void init() {
ServletConfig config = getServletConfig();
grammarDirectory = config.getInitParameter(INIT_PARAM_GRAM_DIR);
if (grammarDirectory == null) {
grammarDirectory = DEFAULT_GRAM_DIR;
}
ServletContext application = getServletContext();
jar = application.getRealPath(config.getInitParameter(INIT_PARAM_JAR));
if (jar == null) {
jar = application.getRealPath(DEFAULT_JAR);
}
}
/**
* This method is called by the container for each GET request.
*
* Grammar to extract is specified as part of the URL
* We extract this from PathInfo, and serve the specified
* grammar from the RDC jar file.
*/
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
MessageFormat msgFormat;
String errMsg;
try {
JarFile j = new JarFile (jar);
// locate desired entry name from PATHINFO
// Notice that are servlet mapping rule consumes
// component "grammar" from the URL
String p = grammarDirectory + request.getPathInfo();
JarEntry e = j.getJarEntry(p);
if (e == null) {
msgFormat = new MessageFormat(ERR_NO_SUCH_ENTRY);
errMsg = msgFormat.format(new Object[] {p, jar});
// Log error and send bad response
log.error(errMsg);
PrintWriter out = response.getWriter();
out.println(errMsg);
return;
} // end of if (e != null)
InputStream i = j.getInputStream(e);
if (i == null) {
msgFormat = new MessageFormat(ERR_NO_INPUT_STREAM);
errMsg = msgFormat.format(new Object[] {p, jar});
log.error(errMsg);
PrintWriter out = response.getWriter();
out.println(errMsg);
return;
} // end of if (i == nul)
//copy entry to output
response.setContentLength((int)e.getSize());
// We only serve JavaScript files or SRGS grammar files
// out of the .grammar directory.
// Thanks Stu for the mime types!
if (p.endsWith( EXT_JAVASCRIPT )) {
response.setContentType( MIME_JAVASCRIPT );
} else {
response.setContentType( MIME_SRGS_GRAM );
}
copy (i, response);
} catch (SecurityException e) {
msgFormat = new MessageFormat(ERR_NO_PERMISSION);
errMsg = msgFormat.format(new Object[] {jar});
log.error(errMsg);
PrintWriter out = response.getWriter();
out.println(errMsg);
} // end of try-catch
}
/**
* This method is called once by the container just before the servlet
* is taken out of service.
*
*/
public void destroy() {
jar = null;
grammarDirectory = null;
}
/**
* This way please
*/
private void copy (InputStream i, HttpServletResponse response)
throws IOException {
ServletOutputStream out = response.getOutputStream();
byte[] b = new byte[ 1024 ];
while( true ) {
int bytes = i.read( b);
if( bytes == -1 ) {
break;
}
out.write( b, 0, bytes );
}
i.close();
out.flush();
}
}