JdbcMapper/beehive-netui-tags/src/main/java/org/apache/beehive/netui/tags/html/HtmlBaseTag.java

587 lines
23 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.html;
import org.apache.beehive.netui.tags.AbstractClassicTag;
import org.apache.beehive.netui.tags.IAttributeConsumer;
import org.apache.beehive.netui.tags.IHtmlAttrs;
import org.apache.beehive.netui.tags.TagConfig;
import org.apache.beehive.netui.tags.javascript.ScriptRequestState;
import org.apache.beehive.netui.tags.rendering.AbstractHtmlControlState;
import org.apache.beehive.netui.tags.rendering.AbstractHtmlState;
import org.apache.beehive.netui.util.Bundle;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
/**
* [Base] Anchor, Form, Image, ImageAnchor (Image), Label, SelectOption
* [FocusBase] Button, CheckBoxOption, ImageButton, RadioButtonOption
* [DataSource] FileUpload
* [DefaultableDatSource] CheckBox, TextArea, TextBox
* [OptionsDataSource] Select
* [GroupDataSource] CheckBoxGroup, RadioButtonGroup
*/
abstract public class HtmlBaseTag extends AbstractClassicTag
implements HtmlConstants, IAttributeConsumer, IHtmlAttrs
{
/**
* This method will return the state associated with the tag. This is used by this
* base class to access the individual state objects created by the tags.
* @return a subclass of the <code>AbstractHtmlState</code> class.
*/
abstract protected AbstractHtmlState getState();
//***************************** The IHtmlCore properties *********************************/
/**
* Sets the style of the rendered html tag.
* @param style the html style.
* @jsptagref.attributedescription Specifies style information for the current element.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_style</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="Specifies style information for the current element."
*/
public void setStyle(String style)
{
if ("".equals(style))
return;
AbstractHtmlState tsh = getState();
tsh.style = style;
}
/**
* Sets the style class of the rendered html tag.
* @param styleClass the html style class.
* @jsptagref.attributedescription The style class (a style sheet selector).
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_styleClass</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="The style class (a style sheet selector)."
*/
public void setStyleClass(String styleClass)
{
if ("".equals(styleClass))
return;
AbstractHtmlState tsh = getState();
tsh.styleClass = styleClass;
}
/**
* Set the ID of the tag.
* @param id the tagId. A value is required.
* @jsptagref.attributedescription <p>String value. Sets the <code>id</code> (or <code>name</code>) attribute of the rendered HTML tag.
* Note that the real id attribute rendered in the browser may be
* changed by the application container (for example, Portal containers may change
* the rendered id value to ensure the uniqueness of
* id's on the page). In this case, the real id rendered
* in the browser may be looked up
* through the JavaScript function <code>lookupIdByTagId( tagId, tag )</code>.
*
* <p>For example, assume that some tag's <code>tagId</code> attribute is set to <code>foo</code>.
*
* <pre> &lt;netui:textBox <b>tagId="foo"</b> /></pre>
*
* <p>Then the following JavaScript function will return the real id attribute rendered in the browser:
*
* <pre> lookupIdByTagId( "foo", this )</pre>
*
* <p>To get a &lt;netui:form> element and all of its children elements in JavaScript, use
* the same JavaScript function <code>lookupIdByTagId( tagId, tag )</code>. For example,
* assume that there is a &lt;netui:form> whose
* tagId attribute is set to <code>bar</code>.
*
* <pre> &lt;netui:form <b>tagId="bar"</b> ></pre>
*
* <p>Then the following JavaScript function will return the &lt;netui:form> element
* and its children (packaged as an array).
*
* <pre> document[lookupIdByTagId( "bar", this )]</pre>
*
* <p>To retreive the value entered into a &lt;netui:textBox> within the &lt;netui:form> tag, use the following
* JavaScript expression.
*
* <pre> document[lookupIdByTagId("bar", this)][lookupIdByTagId("foo", this)].value</pre>
*
* <p>The second parameter ensures that the JavaScript function
* begins its search within the correct Portlet scope. Pass the
* JavaScript keyword <code>this</code> as the second parameter.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_tagId</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="String value. Sets the id (or name) attribute of the rendered HTML tag. "
*/
public void setId(String id)
{
super.setId(id);
try {
setTagId(id);
} catch (JspException e) {
e.printStackTrace();
}
}
/**
* Return the ID of the tag. The id may be rewritten by the container (such
* as a portal) to make sure it is unique. JavaScript may lookup the actual id
* of the element by looking it up in the <code>netui_names</code> table written
* into the HTML.
* @return the tagId.
*/
public String getId()
{
return getTagId();
}
/**
* Set the ID of the tag.
* @param tagId the tagId. A value is required.
* @jsptagref.attributedescription <p>String value. Sets the <code>id</code> (or <code>name</code>) attribute of the rendered HTML tag.
* Note that the real id attribute rendered in the browser may be
* changed by the application container (for example, Portal containers may change
* the rendered id value to ensure the uniqueness of
* id's on the page). In this case, the real id rendered
* in the browser may be looked up
* through the JavaScript function <code>lookupIdByTagId( tagId, tag )</code>.
*
* <p>For example, assume that some tag's <code>tagId</code> attribute is set to <code>foo</code>.
*
* <pre> &lt;netui:textBox <b>tagId="foo"</b> /></pre>
*
* <p>Then the following JavaScript function will return the real id attribute rendered in the browser:
*
* <pre> lookupIdByTagId( "foo", this )</pre>
*
* <p>To get a &lt;netui:form> element and all of its children elements in JavaScript, use
* the same JavaScript function <code>lookupIdByTagId( tagId, tag )</code>. For example,
* assume that there is a &lt;netui:form> whose
* tagId attribute is set to <code>bar</code>.
*
* <pre> &lt;netui:form <b>tagId="bar"</b> ></pre>
*
* <p>Then the following JavaScript function will return the &lt;netui:form> element
* and its children (packaged as an array).
*
* <pre> document[lookupIdByTagId( "bar", this )]</pre>
*
* <p>To retreive the value entered into a &lt;netui:textBox> within the &lt;netui:form> tag, use the following
* JavaScript expression.
*
* <pre> document[lookupIdByTagId("bar", this)][lookupIdByTagId("foo", this)].value</pre>
*
* <p>The second parameter ensures that the JavaScript function
* begins its search within the correct Portlet scope. Pass the
* JavaScript keyword <code>this</code> as the second parameter.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_tagId</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="String value. Sets the id (or name) attribute of the rendered HTML tag. "
*/
public void setTagId(String tagId)
throws JspException
{
// JSP 2.0 EL will convert a null into a empty string "".
// If we get a "" we will display an error.
AbstractHtmlState tsh = getState();
tsh.id = setRequiredValueAttribute(tagId, "tagId");
}
/**
* Return the ID of the tag. The id may be rewritten by the container (such
* as a portal) to make sure it is unique. JavaScript may lookup the actual id
* of the element by looking it up in the <code>netui_names</code> table written
* into the HTML.
* @return the tagId.
*/
public String getTagId()
{
AbstractHtmlState tsh = getState();
return tsh.id;
}
/**
* Sets the value of the title attribute.
* @param title
* @jsptagref.attributedescription The title.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_title</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="The title. "
*/
public void setTitle(String title)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TITLE, title);
}
/******************** the HtmlI18n properties ******************************************/
/**
* Sets the lang attribute for the HTML element.
* @param lang
* @jsptagref.attributedescription Sets the language code for the base language of an
* element's attribute values and text content.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_lang</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="Sets the language code for the base language of an element's attribute values and text content."
*/
public void setLang(String lang)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_GENERAL, LANG, lang);
}
/**
* Sets the dir attribute for the HTML element.
* @param dir
* @jsptagref.attributedescription Specifies the direction of text. (<code>LTR | RTL</code>)
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_dir</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="Specifies the direction of text. (LTR | RTL)"
*/
public void setDir(String dir)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_GENERAL, DIR, dir);
}
//******************* the HtmlEvent Properties ****************************************
/**
* Gets the onClick javascript event.
* @return the onClick event.
*/
public String getOnClick()
{
AbstractHtmlState tsh = getState();
return tsh.getAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONCLICK);
}
/**
* Sets the onClick javascript event.
* @param onclick the onClick event.
* @jsptagref.attributedescription The onClick JavaScript event.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_onClick</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="The onClick JavaScript event."
*/
public void setOnClick(String onclick)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONCLICK, onclick);
}
/**
* Sets the onDblClick javascript event.
* @param ondblclick the onDblClick event.
* @jsptagref.attributedescription The onDblClick JavaScript event.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_onDblClick</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="The onDblClick JavaScript event."
*/
public void setOnDblClick(String ondblclick)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONDBLCLICK, ondblclick);
}
/**
* Sets the onKeyDown javascript event.
* @param onkeydown the onKeyDown event.
* @jsptagref.attributedescription The onKeyDown JavaScript event.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_onKeyDown</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="The onKeyDown JavaScript event."
*/
public void setOnKeyDown(String onkeydown)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONKEYDOWN, onkeydown);
}
/**
* Sets the onKeyPress javascript event.
* @param onkeypress the onKeyPress event.
* @jsptagref.attributedescription The onKeyPress JavaScript event.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_onKeyPress</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="The onKeyPress JavaScript event."
*/
public void setOnKeyPress(String onkeypress)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONKEYPRESS, onkeypress);
}
/**
* Sets the onKeyUp javascript event.
* @param onkeyup the onKeyUp event.
* @jsptagref.attributedescription The onKeyUp JavaScript event.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_onKeyUp</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="The onKeyUp JavaScript event."
*/
public void setOnKeyUp(String onkeyup)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONKEYUP, onkeyup);
}
/**
* Sets the onMouseDown javascript event.
* @param onmousedown the onMouseDown event.
* @jsptagref.attributedescription The onMouseDown JavaScript event.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_onMouseDown</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="The onMouseDown JavaScript event."
*/
public void setOnMouseDown(String onmousedown)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONMOUSEDOWN, onmousedown);
}
/**
* Sets the onMouseMove javascript event.
* @param onmousemove the onMouseMove event.
* @jsptagref.attributedescription The onMouseMove JavaScript event.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_onMouseMove</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="The onMouseMove JavaScript event."
*/
public void setOnMouseMove(String onmousemove)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONMOUSEMOVE, onmousemove);
}
/**
* Sets the onMouseOut javascript event.
* @param onmouseout the onMouseOut event.
* @jsptagref.attributedescription The onMouseOut JavaScript event.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_onMouseOut</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="The onMouseOut JavaScript event."
*/
public void setOnMouseOut(String onmouseout)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONMOUSEOUT, onmouseout);
}
/**
* Sets the onMouseOver javascript event.
* @param onmouseover the onMouseOver event.
* @jsptagref.attributedescription The onMouseOver JavaScript event.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_onMouseOver</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="The onMouseOver JavaScript event."
*/
public void setOnMouseOver(String onmouseover)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONMOUSEOVER, onmouseover);
}
/**
* Sets the onMouseUp javascript event.
* @param onmouseup the onMouseUp event.
* @jsptagref.attributedescription The onMouseUp JavaScript event.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue <i>string_onMouseUp</i>
* @netui:attribute required="false" rtexprvalue="true"
* description="The onMouseUp JavaScript event."
*/
public void setOnMouseUp(String onmouseup)
{
AbstractHtmlState tsh = getState();
tsh.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONMOUSEUP, onmouseup);
}
//******************* Helper Routines *********************************/
protected String getJavaScriptAttribute(String name)
{
AbstractHtmlState tsh = getState();
return tsh.getAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, name);
}
/**
* Attribute implementation.
* @param name
* @param value
* @param tsh
* @throws JspException
*/
protected void setStateAttribute(String name, String value, AbstractHtmlState tsh)
throws JspException
{
boolean error = false;
// validate the name attribute, in the case of an error simply return.
if (name == null || name.length() <= 0) {
String s = Bundle.getString("Tags_AttributeNameNotSet");
registerTagError(s, null);
error = true;
}
// it's not legal to set the id or name attributes this way
if (name != null && (name.equals(ID) || name.equals(NAME))) {
String s = Bundle.getString("Tags_AttributeMayNotBeSet", new Object[]{name});
registerTagError(s, null);
}
if (error)
return;
// if there is a style or class we will let them override the base
if (name.equals(CLASS)) {
tsh.styleClass = value;
return;
}
else if (name.equals(STYLE)) {
tsh.style = value;
return;
}
tsh.registerAttribute(AbstractHtmlState.ATTR_GENERAL, name, value);
}
/**
* Base support for the <code>attribute</code> tag. This requires that the tag buffer their body and
* write attribute in the end tag. For the HTML tags it is not legal to set
* the <code>id</code> or <code>name</code> attributes. In addition, the base tag does
* not allow facets to be set. If the attribute is legal it will be added to the
* general expression map stored in the <code>AbstractHtmlState</code> of the tag.
* @param name The name of the attribute. This value may not be null or the empty string.
* @param value The value of the attribute. This may contain an expression.
* @param facet The name of a facet to which the attribute will be applied. This is optional.
* @throws JspException A JspException may be thrown if there is an error setting the attribute.
*/
public void setAttribute(String name, String value, String facet)
throws JspException
{
if (facet != null) {
String s = Bundle.getString("Tags_AttributeFacetNotSupported", new Object[]{facet});
registerTagError(s, null);
}
AbstractHtmlState tsh = getState();
setStateAttribute(name, value, tsh);
}
/**
* Assumptions:
* <ul>
* <li>The state.name must be fully formed or the "real name" of the form.</li>
* <li>The state.id is the tagId value set on the tag and <b>has not</b> be rewritten yet to form the "real id"</li>
* </ul>
* @param state
* @param parentForm
* @return String
*/
protected final String renderNameAndId(HttpServletRequest request, AbstractHtmlState state, Form parentForm)
{
// if id is not set then we need to exit
if (state.id == null)
return null;
// check to see if this is an instance of a HTML Control
boolean ctrlState = (state instanceof AbstractHtmlControlState);
// form keeps track of this so that it can add this control to it's focus map
if (parentForm != null && ctrlState) {
AbstractHtmlControlState hcs = (AbstractHtmlControlState) state;
if (hcs.name == null && parentForm.isFocusSet())
hcs.name = state.id;
parentForm.addTagID(state.id, ((AbstractHtmlControlState) state).name);
}
// rewrite the id, save the original value so it can be used in maps
String id = state.id;
state.id = getIdForTagId(id);
// Legacy Java Script support -- This writes out a single table with both the id and names
// mixed. This is legacy support to match the pre beehive behavior.
String idScript = null;
if (TagConfig.isLegacyJavaScript()) {
ScriptRequestState srs = ScriptRequestState.getScriptRequestState(request);
if (!ctrlState) {
idScript = srs.mapLegacyTagId(getScriptReporter(), id, state.id);
}
else {
AbstractHtmlControlState cState = (AbstractHtmlControlState) state;
if (cState.name != null)
idScript = srs.mapLegacyTagId(getScriptReporter(), id, cState.name);
else
idScript = srs.mapLegacyTagId(getScriptReporter(), id, state.id);
}
}
// map the tagId to the real id
String name = null;
if (ctrlState) {
AbstractHtmlControlState cState = (AbstractHtmlControlState) state;
name = cState.name;
}
String script = renderDefaultNameAndId((HttpServletRequest) pageContext.getRequest(), state, id, name);
if (script != null) {
if (idScript != null) {
idScript = idScript + script;
}
else {
idScript = script;
}
}
return idScript;
}
protected String renderDefaultNameAndId(HttpServletRequest request, AbstractHtmlState state, String id, String name)
{
// map the tagId to the real id
String script = null;
if (TagConfig.isDefaultJavaScript()) {
ScriptRequestState srs = ScriptRequestState.getScriptRequestState(request);
script = srs.mapTagId(getScriptReporter(), id, state.id, name);
}
return script;
}
/**
* Free the state variables of this base class.
*/
protected void localRelease()
{
super.localRelease();
}
}