/* * 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 AbstractHtmlState 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 string_style * @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 string_styleClass * @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

String value. Sets the id (or name) 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 lookupIdByTagId( tagId, tag ). * *

For example, assume that some tag's tagId attribute is set to foo. * *

    <netui:textBox tagId="foo" />
* *

Then the following JavaScript function will return the real id attribute rendered in the browser: * *

    lookupIdByTagId( "foo", this )
* *

To get a <netui:form> element and all of its children elements in JavaScript, use * the same JavaScript function lookupIdByTagId( tagId, tag ). For example, * assume that there is a <netui:form> whose * tagId attribute is set to bar. * *

    <netui:form tagId="bar" >
* *

Then the following JavaScript function will return the <netui:form> element * and its children (packaged as an array). * *

    document[lookupIdByTagId( "bar", this )]
* *

To retreive the value entered into a <netui:textBox> within the <netui:form> tag, use the following * JavaScript expression. * *

    document[lookupIdByTagId("bar", this)][lookupIdByTagId("foo", this)].value
* *

The second parameter ensures that the JavaScript function * begins its search within the correct Portlet scope. Pass the * JavaScript keyword this as the second parameter. * @jsptagref.databindable false * @jsptagref.attributesyntaxvalue string_tagId * @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 netui_names 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

String value. Sets the id (or name) 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 lookupIdByTagId( tagId, tag ). * *

For example, assume that some tag's tagId attribute is set to foo. * *

    <netui:textBox tagId="foo" />
* *

Then the following JavaScript function will return the real id attribute rendered in the browser: * *

    lookupIdByTagId( "foo", this )
* *

To get a <netui:form> element and all of its children elements in JavaScript, use * the same JavaScript function lookupIdByTagId( tagId, tag ). For example, * assume that there is a <netui:form> whose * tagId attribute is set to bar. * *

    <netui:form tagId="bar" >
* *

Then the following JavaScript function will return the <netui:form> element * and its children (packaged as an array). * *

    document[lookupIdByTagId( "bar", this )]
* *

To retreive the value entered into a <netui:textBox> within the <netui:form> tag, use the following * JavaScript expression. * *

    document[lookupIdByTagId("bar", this)][lookupIdByTagId("foo", this)].value
* *

The second parameter ensures that the JavaScript function * begins its search within the correct Portlet scope. Pass the * JavaScript keyword this as the second parameter. * @jsptagref.databindable false * @jsptagref.attributesyntaxvalue string_tagId * @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 netui_names 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 string_title * @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 string_lang * @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. (LTR | RTL) * @jsptagref.databindable false * @jsptagref.attributesyntaxvalue string_dir * @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 string_onClick * @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 string_onDblClick * @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 string_onKeyDown * @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 string_onKeyPress * @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 string_onKeyUp * @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 string_onMouseDown * @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 string_onMouseMove * @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 string_onMouseOut * @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 string_onMouseOver * @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 string_onMouseUp * @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 attribute 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 id or name 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 AbstractHtmlState 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: *

* @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(); } }