to set their default language and time zone preferences; added footer text and account signup accept/decline rules; added additional implementation of dictyionary code for future; minor cleanup of rendering config; and so forth
425 lines
15 KiB
Java
425 lines
15 KiB
Java
/*
|
|
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
* (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.mozilla.org/MPL/>.
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
|
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
|
* language governing rights and limitations under the License.
|
|
*
|
|
* The Original Code is the Venice Web Communities System.
|
|
*
|
|
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
|
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
|
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
package com.silverwrist.venice.servlets.format;
|
|
|
|
import java.io.*;
|
|
import java.util.*;
|
|
import javax.servlet.*;
|
|
import javax.servlet.http.*;
|
|
import javax.xml.parsers.*;
|
|
import org.apache.log4j.*;
|
|
import org.w3c.dom.*;
|
|
import org.xml.sax.SAXException;
|
|
import org.xml.sax.SAXParseException;
|
|
import com.silverwrist.util.DOMElementHelper;
|
|
import com.silverwrist.util.StringUtil;
|
|
import com.silverwrist.venice.core.ConfigException;
|
|
import com.silverwrist.venice.core.UserContext;
|
|
import com.silverwrist.venice.servlets.Variables;
|
|
|
|
public class RenderConfig
|
|
{
|
|
/*--------------------------------------------------------------------------------
|
|
* Static data values
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
protected static final String ATTR_NAME = "com.silverwrist.venice.servlets.RenderConfig";
|
|
protected static final String CONFIG_FILE_PARAM = "render.config";
|
|
|
|
private static Category logger = Category.getInstance(RenderConfig.class.getName());
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Attributes
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
private Document config;
|
|
private String site_title;
|
|
private boolean want_comments;
|
|
private boolean allow_gzip;
|
|
private String font_face;
|
|
private String image_url;
|
|
private String static_url;
|
|
private String site_logo;
|
|
private Hashtable stock_messages;
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Constructor
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
protected RenderConfig(String config_file) throws ConfigException
|
|
{
|
|
config = loadConfiguration(config_file);
|
|
|
|
// Make sure the configuration is valid...
|
|
Element root = config.getDocumentElement();
|
|
if (!(root.getTagName().equals("render-config")))
|
|
{ // not the correct root tag name
|
|
logger.fatal("config document is not a <render-config/> document (root tag: <"
|
|
+ root.getTagName() + "/>)");
|
|
throw new ConfigException("document is not a <render-config/> document",root);
|
|
|
|
} // end if
|
|
|
|
// Get the site name.
|
|
DOMElementHelper root_h = new DOMElementHelper(root);
|
|
site_title = root_h.getSubElementText("site-name");
|
|
if (site_title==null)
|
|
{ // no <site-name/> section - bail out now!
|
|
logger.fatal("config document has no <site-title/> element");
|
|
throw new ConfigException("no <site-title/> section found in config file",root);
|
|
|
|
} // end if
|
|
|
|
if (logger.isDebugEnabled())
|
|
logger.debug("Site title: " + site_title);
|
|
|
|
Element render_sect = root_h.getSubElement("rendering");
|
|
if (render_sect==null)
|
|
{ // no <rendering/> section - bail out now!
|
|
logger.fatal("config document has no <rendering/> section");
|
|
throw new ConfigException("no <rendering/> section found in config file",root);
|
|
|
|
} // end if
|
|
|
|
DOMElementHelper render_sect_h = new DOMElementHelper(render_sect);
|
|
want_comments = render_sect_h.hasChildElement("html-comments");
|
|
allow_gzip = render_sect_h.hasChildElement("gzip-output");
|
|
if (logger.isDebugEnabled())
|
|
{ // log the read values
|
|
logger.debug("Use HTML comments: " + String.valueOf(want_comments));
|
|
logger.debug("Use GZIP encoding: " + String.valueOf(allow_gzip));
|
|
|
|
} // end if
|
|
|
|
font_face = render_sect_h.getSubElementText("font");
|
|
if (font_face==null)
|
|
{ // no <font/> tag - bail out now!
|
|
logger.fatal("<rendering/> section has no <font/> element");
|
|
throw new ConfigException("no <font/> found in <rendering/> section",render_sect);
|
|
|
|
} // end if
|
|
|
|
if (logger.isDebugEnabled())
|
|
logger.debug("Font face: " + font_face);
|
|
|
|
Element paths_sect = root_h.getSubElement("paths");
|
|
if (paths_sect==null)
|
|
{ // no <paths/> section - bail out now!
|
|
logger.fatal("config document has no <paths/> section");
|
|
throw new ConfigException("no <paths/> section found in config file",root);
|
|
|
|
} // end if
|
|
|
|
DOMElementHelper paths_sect_h = new DOMElementHelper(paths_sect);
|
|
image_url = paths_sect_h.getSubElementText("image");
|
|
if (image_url==null)
|
|
{ // no <image/> tag - bail out now!
|
|
logger.fatal("<paths/> section has no <image/> element");
|
|
throw new ConfigException("no <image/> found in <paths/> section",paths_sect);
|
|
|
|
} // end if
|
|
|
|
if (logger.isDebugEnabled())
|
|
logger.debug("Image path: " + image_url);
|
|
|
|
static_url = paths_sect_h.getSubElementText("static");
|
|
if (static_url==null)
|
|
{ // no <static/> tag - bail out now!
|
|
logger.fatal("<paths/> section has no <static/> element");
|
|
throw new ConfigException("no <static/> found in <paths/> section",paths_sect);
|
|
|
|
} // end if
|
|
|
|
if (logger.isDebugEnabled())
|
|
logger.debug("Static files path: " + static_url);
|
|
|
|
site_logo = paths_sect_h.getSubElementText("site-logo");
|
|
if (site_logo==null)
|
|
{ // no <image/> tag - bail out now!
|
|
logger.fatal("<paths/> section has no <site-logo/> element");
|
|
throw new ConfigException("no <site-logo/> found in <paths/> section",paths_sect);
|
|
|
|
} // end if
|
|
|
|
if (logger.isDebugEnabled())
|
|
logger.debug("Site logo: " + image_url);
|
|
|
|
Element msg_sect = root_h.getSubElement("messages");
|
|
if (msg_sect==null)
|
|
{ // no <messages/> section - bail out now!
|
|
logger.fatal("config document has no <messages/> section");
|
|
throw new ConfigException("no <messages/> section found in config file",root);
|
|
|
|
} // end if
|
|
|
|
// Initialize the stock messages list.
|
|
stock_messages = new Hashtable();
|
|
NodeList msg_nodes = msg_sect.getChildNodes();
|
|
for (int i=0; i<msg_nodes.getLength(); i++)
|
|
{ // examine all subnodes to add them to the message text
|
|
Node msgn = msg_nodes.item(i);
|
|
if (msgn.getNodeType()==Node.ELEMENT_NODE)
|
|
{ // add it to the hash table by its tag name
|
|
Element msgel = (Element)msgn;
|
|
DOMElementHelper h = new DOMElementHelper(msgel);
|
|
String txt = h.getElementText();
|
|
if (txt!=null)
|
|
stock_messages.put(msgel.getTagName(),txt.trim());
|
|
|
|
} // end if
|
|
|
|
} // end for
|
|
|
|
if (logger.isDebugEnabled())
|
|
logger.debug(stock_messages.size() + " stock messages loaded from config");
|
|
|
|
} // end constructor
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Internal functions
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
private static Document loadConfiguration(String configname) throws ConfigException
|
|
{
|
|
try
|
|
{ // create a simple DOM parser by using the Java XML parsing API
|
|
DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
|
|
fac.setNamespaceAware(false);
|
|
fac.setValidating(false);
|
|
DocumentBuilder parser = fac.newDocumentBuilder();
|
|
|
|
// access the config file and parse it into our config data tree
|
|
File configfile = new File(configname);
|
|
Document rc = parser.parse(configfile);
|
|
if (logger.isDebugEnabled())
|
|
logger.debug("configuration loaded successfully");
|
|
return rc;
|
|
|
|
} // end try
|
|
catch (FactoryConfigurationError e1)
|
|
{ // if the document builder factory could not be created
|
|
logger.fatal("Parser factory configuration error: " + e1.getMessage(),e1);
|
|
throw new ConfigException("XML parser factory could not be created - " + e1.getMessage());
|
|
|
|
} // end catch
|
|
catch (ParserConfigurationException e2)
|
|
{ // if the XML parser itself could not be created
|
|
logger.fatal("Parser configuration error: " + e2.getMessage(),e2);
|
|
throw new ConfigException("XML parser could not be created - " + e2.getMessage(),e2);
|
|
|
|
} // end catch
|
|
catch (SAXException e3)
|
|
{ // if the XML parser choked on our document
|
|
if (e3 instanceof SAXParseException)
|
|
{ // we have a detailed message - make a proper exception
|
|
SAXParseException e3a = (SAXParseException)e3;
|
|
logger.fatal("Config file error [" + configname + ":" + e3a.getLineNumber() + ","
|
|
+ e3a.getColumnNumber() + "]: " + e3a.getMessage(),e3a);
|
|
throw new ConfigException("Configuration file error: " + e3a.getMessage() + " at line "
|
|
+ e3a.getLineNumber() + ", column " + e3a.getColumnNumber(),e3a);
|
|
|
|
} // end if
|
|
else
|
|
{ // generic exception - just send up a simple error message
|
|
logger.fatal("Config file error [" + configname + "]: " + e3.getMessage(),e3);
|
|
throw new ConfigException("Configuration file error - " + e3.getMessage(),e3);
|
|
|
|
} // end else
|
|
|
|
} // end catch
|
|
catch (IOException e4)
|
|
{ // error reading the config file itself off the disk
|
|
logger.fatal("IO error reading config: " + e4.getMessage(),e4);
|
|
throw new ConfigException("unable to read config file \"" + configname + "\" - " + e4.getMessage(),e4);
|
|
|
|
} // end catch
|
|
|
|
} // end loadConfiguration
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* External operations usable only by RenderData
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
boolean useHTMLComments()
|
|
{
|
|
return want_comments;
|
|
|
|
} // end useHTMLComments
|
|
|
|
boolean isGZIPAllowed()
|
|
{
|
|
return allow_gzip;
|
|
|
|
} // end isGZIPAllowed
|
|
|
|
String getFullImagePath(String name)
|
|
{
|
|
StringBuffer buf = new StringBuffer();
|
|
buf.append(image_url).append(name);
|
|
return buf.toString();
|
|
|
|
} // end getFullImagePath
|
|
|
|
String getStaticFilePath(String name)
|
|
{
|
|
StringBuffer buf = new StringBuffer();
|
|
buf.append(static_url).append(name);
|
|
return buf.toString();
|
|
|
|
} // end getStaticFilePath
|
|
|
|
String getTitleTag(String specific)
|
|
{
|
|
StringBuffer buf = new StringBuffer();
|
|
buf.append("<TITLE>").append(specific).append(" - ").append(site_title).append("</TITLE>");
|
|
return buf.toString();
|
|
|
|
} // end getTitleTag
|
|
|
|
String getSiteImageTag(int hspace, int vspace)
|
|
{
|
|
StringBuffer buf = new StringBuffer();
|
|
buf.append("<IMG SRC=\"").append(site_logo).append("\" ALT=\"").append(site_title);
|
|
buf.append("\" WIDTH=140 HEIGHT=80 BORDER=0");
|
|
if (hspace>0)
|
|
buf.append(" HSPACE=").append(hspace);
|
|
if (vspace>0)
|
|
buf.append(" VSPACE=").append(vspace);
|
|
buf.append('>');
|
|
return buf.toString();
|
|
|
|
} // end getSiteImageTag
|
|
|
|
String getStdFontTag(String color, int size)
|
|
{
|
|
StringBuffer buf = new StringBuffer("<FONT FACE=\"");
|
|
buf.append(font_face).append("\" SIZE=").append(size);
|
|
if (color!=null)
|
|
buf.append(" COLOR=\"").append(color).append("\"");
|
|
buf.append('>');
|
|
return buf.toString();
|
|
|
|
} // end getStdFontTag
|
|
|
|
String getStdBaseFontTag(int size)
|
|
{
|
|
StringBuffer buf = new StringBuffer("<BASEFONT FACE=\"");
|
|
buf.append(font_face).append("\" SIZE=").append(size).append('>');
|
|
return buf.toString();
|
|
|
|
} // end getStdBaseFontTag
|
|
|
|
public String getRequiredBullet()
|
|
{
|
|
StringBuffer buf = new StringBuffer("<FONT FACE=\"");
|
|
buf.append(font_face).append("\" COLOR=\"red\">*</FONT>");
|
|
return buf.toString();
|
|
|
|
} // end getRequiredBullet
|
|
|
|
void writeFooter(Writer out) throws IOException
|
|
{
|
|
out.write("<HR WIDTH=\"80%\">\n<TABLE ALIGN=CENTER BORDER=0 CELLPADDING=0 CELLSPACING=6><TR VALIGN=TOP>"
|
|
+ "\n<TD ALIGN=RIGHT>\n");
|
|
out.write(getStdFontTag(null,1));
|
|
out.write(getStockMessage("footer-text"));
|
|
out.write("</FONT>\n</TD>\n<TD ALIGN=LEFT>\n<A HREF=\"http://venice.sourceforge.net\" TARGET=\"_blank\">"
|
|
+ "<IMG SRC=\"");
|
|
out.write(getFullImagePath("powered-by-venice.gif"));
|
|
out.write("\" ALT=\"Powered by Venice\" WIDTH=140 HEIGHT=80 BORDER=0 HSPACE=0 VSPACE=0></A>\n</TD>\n"
|
|
+ "</TR></TABLE>\n");
|
|
|
|
} // end writeFooter
|
|
|
|
void writeContentHeader(Writer out, String primary, String secondary) throws IOException
|
|
{
|
|
out.write(getStdFontTag("#3333AA",5) + "<B>" + StringUtil.encodeHTML(primary) + "</B></FONT>");
|
|
if (secondary!=null)
|
|
out.write(" " + getStdFontTag("#3333AA",3) + "<B>" + StringUtil.encodeHTML(secondary)
|
|
+ "</B></FONT>");
|
|
out.write("<HR ALIGN=LEFT SIZE=2 WIDTH=\"90%\" NOSHADE>\n");
|
|
|
|
} // end writeContentHeader
|
|
|
|
String getStockMessage(String identifier)
|
|
{
|
|
return (String)(stock_messages.get(identifier));
|
|
|
|
} // end getStockMessage
|
|
|
|
void writeStockMessage(Writer out, String identifier) throws IOException
|
|
{
|
|
String text = (String)(stock_messages.get(identifier));
|
|
out.write(StringUtil.encodeHTML(text));
|
|
|
|
} // end writeStockMessage
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Static operations for use by VeniceServlet
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
public static RenderConfig getRenderConfig(ServletContext ctxt) throws ServletException
|
|
{
|
|
// Look in the servlet attributes first.
|
|
Object obj = ctxt.getAttribute(ATTR_NAME);
|
|
if (obj!=null)
|
|
return (RenderConfig)obj;
|
|
|
|
// Get the parameter for the renderer's config file.
|
|
String cfgfile = ctxt.getInitParameter(CONFIG_FILE_PARAM);
|
|
logger.info("Initializing Venice rendering using config file: " + cfgfile);
|
|
|
|
try
|
|
{ // create the RenderConfig object and save it to attributes.
|
|
RenderConfig rconf = new RenderConfig(cfgfile);
|
|
ctxt.setAttribute(ATTR_NAME,rconf);
|
|
return rconf;
|
|
|
|
} // end try
|
|
catch (ConfigException e)
|
|
{ // configuration failed! post an error message
|
|
logger.fatal("Rendering configuration failed: " + e.getMessage(),e);
|
|
throw new ServletException("Venice rendering configuration failed: " + e.getMessage(),e);
|
|
|
|
} // end catch
|
|
|
|
} // end getRenderConfig
|
|
|
|
public static RenderData createRenderData(ServletContext ctxt, HttpServletRequest request,
|
|
HttpServletResponse response) throws ServletException
|
|
{
|
|
UserContext uc = Variables.getUserContext(ctxt,request,request.getSession(true));
|
|
return new RenderData(getRenderConfig(ctxt),uc,request,response);
|
|
|
|
} // end createRenderData
|
|
|
|
public static RenderData createRenderData(ServletContext ctxt, UserContext uc, HttpServletRequest request,
|
|
HttpServletResponse response) throws ServletException
|
|
{
|
|
return new RenderData(getRenderConfig(ctxt),uc,request,response);
|
|
|
|
} // end createRenderData
|
|
|
|
} // end class RenderConfig
|