433 lines
16 KiB
Java
433 lines
16 KiB
Java
/*
|
|
* 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.
|
|
*
|
|
* $Header:$
|
|
*/
|
|
package org.apache.beehive.netui.tags.rendering;
|
|
|
|
import org.apache.beehive.netui.tags.html.Html;
|
|
import org.apache.beehive.netui.tags.IDocumentTypeProducer;
|
|
import org.apache.beehive.netui.util.Bundle;
|
|
import org.apache.beehive.netui.util.config.ConfigUtil;
|
|
import org.apache.beehive.netui.util.config.bean.DocType;
|
|
import org.apache.beehive.netui.util.config.bean.JspTagConfig;
|
|
import org.apache.beehive.netui.util.logging.Logger;
|
|
import org.apache.struts.util.ResponseUtils;
|
|
|
|
import javax.servlet.ServletRequest;
|
|
import javax.servlet.jsp.JspException;
|
|
import javax.servlet.jsp.PageContext;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public abstract class TagRenderingBase
|
|
{
|
|
private static final Logger logger = Logger.getInstance(TagRenderingBase.class);
|
|
|
|
/**
|
|
* Unknown Rendering
|
|
*/
|
|
public static final int UNKNOWN_RENDERING = 0;
|
|
|
|
/**
|
|
* Identifier for HTML 4.01 Rendering
|
|
*/
|
|
public static final int HTML_RENDERING = 1;
|
|
|
|
/**
|
|
* Identifier for XHTML Transitional Rendering
|
|
*/
|
|
public static final int XHTML_RENDERING = 2;
|
|
|
|
/**
|
|
* Identifier for HTML 4.01 Rendering in Quirks mode
|
|
*/
|
|
public static final int HTML_RENDERING_QUIRKS = 3;
|
|
|
|
//////////////////////////////////// Supported Rendering Constants ////////////////////////////
|
|
|
|
/**
|
|
* The static initializer will read the netui config file and set the doc type of there is
|
|
* one specified.
|
|
*/
|
|
|
|
private static int _defaultDocType;
|
|
|
|
static
|
|
{
|
|
_defaultDocType = HTML_RENDERING_QUIRKS;
|
|
JspTagConfig tagConfig = ConfigUtil.getConfig().getJspTagConfig();
|
|
if (tagConfig != null) {
|
|
DocType docType = tagConfig.getDocType();
|
|
setDefaultDocType(docType);
|
|
}
|
|
}
|
|
|
|
public static int getDefaultDocType()
|
|
{
|
|
return _defaultDocType;
|
|
}
|
|
|
|
public static void setDefaultDocType(DocType docType)
|
|
{
|
|
if (docType != null) {
|
|
if (docType == DocType.HTML4_LOOSE)
|
|
_defaultDocType = TagRenderingBase.HTML_RENDERING;
|
|
else if (docType == DocType.HTML4_LOOSE_QUIRKS)
|
|
_defaultDocType = TagRenderingBase.HTML_RENDERING_QUIRKS;
|
|
else if (docType== DocType.XHTML1_TRANSITIONAL)
|
|
_defaultDocType = TagRenderingBase.XHTML_RENDERING;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Token identifying the Anchor Renderer <a>
|
|
*/
|
|
public static final Object ANCHOR_TAG = new Object();
|
|
public static final Object AREA_TAG = new Object();
|
|
public static final Object BASE_TAG = new Object();
|
|
public static final Object BODY_TAG = new Object();
|
|
public static final Object BR_TAG = new Object();
|
|
public static final Object BUTTON_TAG = new Object();
|
|
public static final Object CAPTION_TAG = new Object();
|
|
public static final Object FORM_TAG = new Object();
|
|
public static final Object IMAGE_TAG = new Object();
|
|
public static final Object INPUT_BOOLEAN_TAG = new Object();
|
|
public static final Object INPUT_FILE_TAG = new Object();
|
|
public static final Object INPUT_HIDDEN_TAG = new Object();
|
|
public static final Object INPUT_IMAGE_TAG = new Object();
|
|
public static final Object INPUT_SUBMIT_TAG = new Object();
|
|
public static final Object INPUT_TEXT_TAG = new Object();
|
|
public static final Object HTML_TAG = new Object();
|
|
public static final Object LABEL_TAG = new Object();
|
|
public static final Object OPTION_TAG = new Object();
|
|
public static final Object SELECT_TAG = new Object();
|
|
public static final Object SPAN_TAG = new Object();
|
|
public static final Object DIV_TAG = new Object();
|
|
public static final Object TABLE_TAG = new Object();
|
|
public static final Object TBODY_TAG = new Object();
|
|
public static final Object TD_TAG = new Object();
|
|
public static final Object TEXT_AREA_TAG = new Object();
|
|
public static final Object TH_TAG = new Object();
|
|
public static final Object THEAD_TAG = new Object();
|
|
public static final Object TFOOT_TAG = new Object();
|
|
public static final Object TR_TAG = new Object();
|
|
public static final Object SCRIPT_TAG = new Object();
|
|
|
|
//////////////////////////////////// Abstract Methods ////////////////////////////
|
|
|
|
/**
|
|
* Render the start tag for an element. The element will render the tag and all of it's
|
|
* attributes into a InternalStringBuilder.
|
|
* @param sb A InternalStringBuilder where the element start tag is appended.
|
|
* @param renderState The state assocated with the element.
|
|
*/
|
|
abstract public void doStartTag(AbstractRenderAppender sb, AbstractTagState renderState);
|
|
|
|
/**
|
|
* Render the end tag for an element. The end tag will be rendered if the tag requires an end tag.
|
|
* @param sb A InternalStringBuilder where the element end tag may be appended.
|
|
*/
|
|
abstract public void doEndTag(AbstractRenderAppender sb);
|
|
|
|
/**
|
|
* @param buf
|
|
* @param name
|
|
*/
|
|
protected final void renderTag(AbstractRenderAppender buf, String name)
|
|
{
|
|
assert (buf != null) : "Parameter 'buf' must not be null.";
|
|
assert (name != null) : "Parameter 'name' must not be null";
|
|
|
|
buf.append("<");
|
|
buf.append(name);
|
|
}
|
|
|
|
/**
|
|
* @param buf
|
|
* @param name
|
|
*/
|
|
protected final void renderEndTag(AbstractRenderAppender buf, String name)
|
|
{
|
|
buf.append("</");
|
|
buf.append(name);
|
|
buf.append(">");
|
|
}
|
|
|
|
/**
|
|
* This method will append an attribute value to a InternalStringBuilder.
|
|
* The method assumes that the attr is not <code>null</code>. If the
|
|
* <code>value</code> attribute is <code>null</code> the attribute will not be appended to the
|
|
* <code>InternalStringBuilder</code>.
|
|
* @param buf The InternalStringBuilder to append the attribute into.
|
|
* @param name The name of the attribute
|
|
* @param value The value of teh attribute. If this is <code>null</code> the attribute will not be written.
|
|
*/
|
|
protected final void renderAttribute(AbstractRenderAppender buf, String name, String value)
|
|
{
|
|
assert (buf != null) : "Parameter 'buf' must not be null.";
|
|
assert (name != null) : "Parameter 'name' must not be null";
|
|
|
|
// without a value lets skip writting this out
|
|
if (value == null)
|
|
return;
|
|
|
|
buf.append(" ");
|
|
buf.append(name);
|
|
buf.append("=\"");
|
|
buf.append(value);
|
|
buf.append("\"");
|
|
}
|
|
|
|
/**
|
|
* @param buf
|
|
* @param name
|
|
* @param value
|
|
*/
|
|
protected final void renderAttributeSingleQuotes(AbstractRenderAppender buf, String name, String value)
|
|
{
|
|
assert (buf != null) : "Parameter 'buf' must not be null.";
|
|
assert (name != null) : "Parameter 'name' must not be null";
|
|
|
|
// without a value lets skip writting this out
|
|
if (value == null)
|
|
return;
|
|
|
|
buf.append(" ");
|
|
buf.append(name);
|
|
buf.append("='");
|
|
buf.append(value);
|
|
buf.append("'");
|
|
}
|
|
|
|
/**
|
|
* Render all of the attributes defined in a map and return the string value. The attributes
|
|
* are rendered with in a name="value" style supported by XML.
|
|
* @param type an integer key indentifying the map
|
|
*/
|
|
protected void renderAttributes(int type, AbstractRenderAppender sb, AbstractAttributeState state, boolean doubleQuote)
|
|
{
|
|
HashMap map = null;
|
|
switch (type) {
|
|
case AbstractAttributeState.ATTR_GENERAL:
|
|
map = state.getGeneralAttributeMap();
|
|
break;
|
|
default:
|
|
String s = Bundle.getString("Tags_ParameterRenderError",
|
|
new Object[]{new Integer(type)});
|
|
logger.error(s);
|
|
throw new IllegalStateException(s);
|
|
}
|
|
renderGeneral(map, sb, doubleQuote);
|
|
}
|
|
|
|
final protected void renderAttributes(int type, AbstractRenderAppender sb, AbstractAttributeState state)
|
|
{
|
|
renderAttributes(type, sb, state, true);
|
|
}
|
|
|
|
/**
|
|
* This method will render all of the general attributes.
|
|
*/
|
|
protected void renderGeneral(HashMap map, AbstractRenderAppender sb, boolean doubleQuote)
|
|
{
|
|
if (map == null)
|
|
return;
|
|
|
|
Iterator iterator = map.keySet().iterator();
|
|
for (; iterator.hasNext();) {
|
|
String key = (String) iterator.next();
|
|
if (key == null)
|
|
continue;
|
|
|
|
String value = (String) map.get(key);
|
|
if (doubleQuote)
|
|
renderAttribute(sb, key, value);
|
|
else
|
|
renderAttributeSingleQuotes(sb, key, value);
|
|
}
|
|
}
|
|
|
|
protected final void write(PageContext pc, String string)
|
|
{
|
|
try {
|
|
ResponseUtils.write(pc, string);
|
|
}
|
|
catch (JspException e) {
|
|
logger.error(Bundle.getString("Tags_WriteException"), e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This is the factory for obtaining a Tag Rendering object. The factory supports to types
|
|
* of renderings HTML 4.01 and XHTML. The factory is responsible for creating the rendering objects and
|
|
* passing them out. The target encoding may be specified on a page by page basis within a WebApp. The
|
|
* <code>getRendering</code> method will return a <code>TagRenderingBase</code> object. This object is always
|
|
* a stateless object. The state needed to render the tag will be passed into the tag.
|
|
*/
|
|
public static class Factory
|
|
{
|
|
private static HashMap _xhtml; // The XHTML TagRenderingBase objects
|
|
private static HashMap _html; // The HTML TagRenderingBase objects
|
|
private static HashMap _htmlQuirks; // THe HTML Quirks TagRenderingBase object
|
|
|
|
private static ConstantRendering _xhtmlConstants;
|
|
private static ConstantRendering _htmlConstants;
|
|
|
|
// create the HashMaps and their static renderings.
|
|
static
|
|
{
|
|
_xhtml = new HashMap(37);
|
|
_html = new HashMap(37);
|
|
_htmlQuirks = new HashMap(37);
|
|
|
|
// build the supported renderers.
|
|
AnchorTag.add(_html, _htmlQuirks, _xhtml);
|
|
AreaTag.add(_html, _htmlQuirks, _xhtml);
|
|
BaseTag.add(_html, _htmlQuirks, _xhtml);
|
|
BodyTag.add(_html, _htmlQuirks, _xhtml);
|
|
ButtonTag.add(_html, _htmlQuirks, _xhtml);
|
|
CaptionTag.add(_html, _htmlQuirks, _xhtml);
|
|
DivTag.add(_html, _htmlQuirks, _xhtml);
|
|
FormTag.add(_html, _htmlQuirks, _xhtml);
|
|
ImageTag.add(_html, _htmlQuirks, _xhtml);
|
|
InputBooleanTag.add(_html, _htmlQuirks, _xhtml);
|
|
InputFileTag.add(_html, _htmlQuirks, _xhtml);
|
|
InputHiddenTag.add(_html, _htmlQuirks, _xhtml);
|
|
InputImageTag.add(_html, _htmlQuirks, _xhtml);
|
|
InputSubmitTag.add(_html, _htmlQuirks, _xhtml);
|
|
InputTextTag.add(_html, _htmlQuirks, _xhtml);
|
|
HtmlTag.add(_html, _htmlQuirks, _xhtml);
|
|
LabelTag.add(_html, _htmlQuirks, _xhtml);
|
|
OptionTag.add(_html, _htmlQuirks, _xhtml);
|
|
SelectTag.add(_html, _htmlQuirks, _xhtml);
|
|
SpanTag.add(_html, _htmlQuirks, _xhtml);
|
|
TableTag.add(_html, _htmlQuirks, _xhtml);
|
|
TBodyTag.add(_html, _htmlQuirks, _xhtml);
|
|
TdTag.add(_html, _htmlQuirks, _xhtml);
|
|
TextAreaTag.add(_html, _htmlQuirks, _xhtml);
|
|
ThTag.add(_html, _htmlQuirks, _xhtml);
|
|
THeadTag.add(_html, _htmlQuirks, _xhtml);
|
|
TFootTag.add(_html, _htmlQuirks, _xhtml);
|
|
TrTag.add(_html, _htmlQuirks, _xhtml);
|
|
ScriptTag.add(_html, _htmlQuirks, _xhtml);
|
|
}
|
|
|
|
/**
|
|
* Factory method for getting a TagRenderingBase for a tag. The default rendering is HTML 4.01.
|
|
* @param token The type of TagRenderingBase to retrieve.
|
|
* @param req The <code>ServletRequest</code> used to see what type of rendering is being done.
|
|
* @return A <code>TagRenderingBase</code>
|
|
*/
|
|
public static TagRenderingBase getRendering(Object token, ServletRequest req)
|
|
{
|
|
int renderingType = getRenderingType(req);
|
|
|
|
// pick the map of renderers
|
|
HashMap h = null;
|
|
switch (renderingType) {
|
|
case HTML_RENDERING:
|
|
h = _html;
|
|
break;
|
|
case HTML_RENDERING_QUIRKS:
|
|
h = _htmlQuirks;
|
|
break;
|
|
case XHTML_RENDERING:
|
|
h = _xhtml;
|
|
break;
|
|
default:
|
|
assert(true) : "Didn't find the map for rendering type:" + renderingType;
|
|
}
|
|
|
|
// return the renderer
|
|
Object o = h.get(token);
|
|
assert(o != null) : "Renderer was not found for [" + token + "] rendering:" + renderingType;
|
|
return (TagRenderingBase) o;
|
|
}
|
|
|
|
/**
|
|
* Return true if the current document is XHTML
|
|
* @param req
|
|
* @return boolean
|
|
*/
|
|
public static boolean isXHTML(ServletRequest req)
|
|
{
|
|
return (getRenderingType(req) == XHTML_RENDERING);
|
|
}
|
|
|
|
private static int getRenderingType(ServletRequest req)
|
|
{
|
|
int renderingType = _defaultDocType;
|
|
Integer reqRender = (Integer) req.getAttribute(Html.DOC_TYPE_OVERRIDE);
|
|
if (reqRender != null) {
|
|
renderingType = ((Integer) reqRender).intValue();
|
|
}
|
|
else {
|
|
IDocumentTypeProducer docProducer = (IDocumentTypeProducer) req.getAttribute(Html.HTML_TAG_ID);
|
|
// the default is html 4.0
|
|
if (docProducer != null) {
|
|
renderingType = docProducer.getTargetDocumentType();
|
|
}
|
|
}
|
|
|
|
return renderingType;
|
|
}
|
|
|
|
/**
|
|
* @param req
|
|
* @return ConstantRendering
|
|
*/
|
|
public static ConstantRendering getConstantRendering(ServletRequest req)
|
|
{
|
|
IDocumentTypeProducer docProducer = (IDocumentTypeProducer) req.getAttribute(Html.HTML_TAG_ID);
|
|
|
|
if (_htmlConstants == null) {
|
|
_htmlConstants = ConstantRendering.getRendering(HTML_RENDERING);
|
|
_xhtmlConstants = ConstantRendering.getRendering(XHTML_RENDERING);
|
|
}
|
|
|
|
// the default is docProducer 4.0
|
|
int renderingType = TagRenderingBase.getDefaultDocType();
|
|
if (docProducer != null) {
|
|
renderingType = docProducer.getTargetDocumentType();
|
|
}
|
|
return (renderingType == XHTML_RENDERING) ? _xhtmlConstants : _htmlConstants;
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param req
|
|
* @return String
|
|
*/
|
|
public static String getAmp(ServletRequest req)
|
|
{
|
|
IDocumentTypeProducer docProducer = (IDocumentTypeProducer) req.getAttribute(Html.HTML_TAG_ID);
|
|
|
|
// the default is docProducer 4.0
|
|
int renderingType = HTML_RENDERING;
|
|
if (docProducer != null) {
|
|
renderingType = docProducer.getTargetDocumentType();
|
|
}
|
|
|
|
// pick the map of renderers
|
|
return (renderingType == XHTML_RENDERING) ? "&" : "&";
|
|
}
|
|
}
|