001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: * $Header:$
018: */
019: package org.apache.beehive.netui.tags.divpanel;
020:
021: import org.apache.beehive.netui.pageflow.requeststate.NameService;
022: import org.apache.beehive.netui.script.ExpressionUpdateException;
023: import org.apache.beehive.netui.script.IllegalExpressionException;
024: import org.apache.beehive.netui.tags.AbstractClassicTag;
025: import org.apache.beehive.netui.tags.ExpressionHandling;
026: import org.apache.beehive.netui.tags.TagConfig;
027: import org.apache.beehive.netui.tags.javascript.CoreScriptFeature;
028: import org.apache.beehive.netui.tags.javascript.IScriptReporter;
029: import org.apache.beehive.netui.tags.javascript.ScriptRequestState;
030: import org.apache.beehive.netui.tags.rendering.AbstractHtmlState;
031: import org.apache.beehive.netui.tags.rendering.DivTag;
032: import org.apache.beehive.netui.tags.rendering.TagRenderingBase;
033: import org.apache.beehive.netui.tags.rendering.WriteRenderAppender;
034: import org.apache.beehive.netui.util.Bundle;
035:
036: import javax.servlet.ServletRequest;
037: import javax.servlet.http.HttpServletRequest;
038: import javax.servlet.jsp.JspException;
039:
040: /**
041: * A DivPanel creates an HTML <div> tag that may contain additional <div> tags. There will only
042: * be a single div that is visible at a time.
043: * @jsptagref.tagdescription Creates an HTML <div> tag that may contain additional <div> tags. Only a single section will be visible at a time.
044: * @netui:tag name="divPanel"
045: * description="A divPanel is an placeholder which may contain multiple sections. Only a single section will be visible at a time."
046: */
047: public class DivPanel extends AbstractClassicTag {
048: private String _tagId;
049: private String _firstPage;
050: private String _dataSource = null; // The name of the tree.
051: private DivTag.State _divState = new DivTag.State();
052:
053: private final String JAVASCRIPT_CLASS = "NetUIDivPanel";
054:
055: public static final String DIVPANEL_JAVASCRIPT_ATTR = "netui-div-panel";
056: public static final String DIVPANEL_FIRST_PAGE = "netui-div-panel-first";
057:
058: public static final String DIVPANEL_DIV_ID = "netui_divpanel_";
059:
060: public static String getCurrentPage(ServletRequest req, String tagId) {
061: String reqId = DIVPANEL_DIV_ID + tagId;
062: String page = req.getParameter(reqId);
063: return page;
064: }
065:
066: /**
067: * Returns the name of the Tag. This is used to
068: * identify the type of tag reporting errors.
069: * @return a constant string representing the name of the tag.
070: */
071: public String getTagName() {
072: return "DivPanel";
073: }
074:
075: /**
076: * Sets an expression which indentifies the DivPanelState which will store the state of the
077: * DivPanel between posts to the server.
078: * @param dataSource the tree attribute name
079: * @jsptagref.attributedescription An expression which identifies which DivPanelState object will store state between posts to the server.
080: * @jsptagref.databindable true
081: * @jsptagref.attributesyntaxvalue <i>expression</i>
082: * @netui:attribute description="Sets an expression which indentifies the DivPanelState storing the state of the
083: * DivPanel between posts."
084: */
085: public void setDataSource(String dataSource) {
086: _dataSource = dataSource;
087: }
088:
089: /**
090: * Set the ID of the tag.
091: * @param tagId the tagId.
092: * @jsptagref.attributedescription Set the ID of the <div> tag
093: * @jsptagref.databindable true
094: * @jsptagref.attributesyntaxvalue <i>string_or_expression</i>
095: * @netui:attribute required="true" rtexprvalue="true"
096: * description="Set the ID of the tag."
097: */
098: public void setTagId(String tagId) {
099: _tagId = tagId;
100: }
101:
102: /**
103: * Set the name of the first page to display.
104: * @param firstPage the name of the first page.
105: * @jsptagref.attributedescription Set the name of the first page to display.
106: * @jsptagref.databindable true
107: * @jsptagref.attributesyntaxvalue <i>string_or_expression</i>
108: * @netui:attribute rtexprvalue="true"
109: * description="Set the name of the first page to display."
110: */
111: public void setFirstPage(String firstPage) {
112: _firstPage = firstPage;
113: }
114:
115: /**
116: * Causes the content of the section to be rendered into a buffer.
117: * @return SKIP_BODY if the visible state is <code>false</code>,
118: * otherwise EVAL_BODY_BUFFERED to cause the body content to be buffered.
119: * @throws javax.servlet.jsp.JspException if there are errors.
120: */
121: public int doStartTag() throws JspException {
122: HttpServletRequest req = (HttpServletRequest) pageContext
123: .getRequest();
124:
125: // if there was a dataSource defined we need to get it based upon the expression
126: // if the variable comes back null, we then create a DivPanelState and set it back
127: // to the property referred to by the expression.
128: DivPanelState state = null;
129: if (_dataSource != null) {
130: ExpressionHandling _expr;
131: _expr = new ExpressionHandling(this );
132: try {
133: state = getState(_expr);
134: } catch (IllegalExpressionException iee) {
135: String s = Bundle.getString("TreeRootError",
136: new Object[] { _dataSource, iee.getMessage() });
137: registerTagError(s, null);
138: return SKIP_BODY;
139: }
140: if (hasErrors())
141: reportAndExit(SKIP_BODY);
142:
143: // if we got here and the state is null then create a new divPanel, and push it back on
144: // the expression
145: if (state == null) {
146: try {
147: state = new DivPanelState();
148: String datasource = "{" + _dataSource + "}";
149: _expr.updateExpression(datasource, state,
150: pageContext);
151: } catch (ExpressionUpdateException e) {
152: String s = Bundle.getString(
153: "Tags_UnableToWriteTree", new Object[] {
154: _dataSource, e.getMessage() });
155: registerTagError(s, null);
156: reportErrors();
157: return SKIP_BODY;
158: }
159:
160: if (hasErrors())
161: reportAndExit(SKIP_BODY);
162:
163: // name the divPanel so we can post state back to this state object.
164: NameService ns = NameService.instance(pageContext
165: .getSession());
166: String name = state.getObjectName();
167: if (name == null) {
168: ns.nameObject("DivPanel", state);
169: ns.put(state);
170: } else if (ns.get(name) == null) {
171: // no longer stored in the NameService, add it.
172: ns.put(state);
173: }
174: }
175: }
176:
177: WriteRenderAppender writer = new WriteRenderAppender(
178: pageContext);
179:
180: // verify hat we are in a container with run at client on...
181: IScriptReporter sr = getScriptReporter();
182: ScriptRequestState srs = ScriptRequestState
183: .getScriptRequestState(req);
184: if (!srs.isFeatureWritten(CoreScriptFeature.DYNAMIC_INIT)) {
185: String s = Bundle.getString("Tags_DivPanelHtmlRunAtClient",
186: null);
187: registerTagError(s, null);
188: reportAndExit(SKIP_BODY);
189: }
190: srs.writeFeature(sr, writer, CoreScriptFeature.DIVPANEL_INIT,
191: true, false, null);
192:
193: // figure out if there is a page to render
194: String page = _firstPage;
195: if (state != null) {
196: String fp = state.getFirstPage();
197: if (fp != null)
198: page = fp;
199: }
200:
201: if (hasErrors())
202: reportAndExit(EVAL_BODY_INCLUDE);
203:
204: _divState.id = this .getIdForTagId(_tagId);
205: _divState.registerAttribute(AbstractHtmlState.ATTR_GENERAL,
206: DIVPANEL_JAVASCRIPT_ATTR, "true");
207: if (page != null)
208: _divState.registerAttribute(AbstractHtmlState.ATTR_GENERAL,
209: DIVPANEL_FIRST_PAGE, page);
210: if (state != null)
211: _divState.registerAttribute(AbstractHtmlState.ATTR_GENERAL,
212: "netui:divName", state.getObjectName());
213:
214: TagRenderingBase divRenderer = TagRenderingBase.Factory
215: .getRendering(TagRenderingBase.DIV_TAG, req);
216: divRenderer.doStartTag(writer, _divState);
217: return EVAL_BODY_INCLUDE;
218: }
219:
220: /**
221: * Stores the buffered body content into the <code>TEMPLATE_SECTIONS
222: * HashMap</code>. The buffered body is
223: * accessed by the template page to obtain
224: * the content for <code>IncludeSection</code> tags.
225: * @return EVAL_PAGE to continue evaluating the page.
226: * @throws JspException on error.
227: */
228: public int doEndTag() throws JspException {
229: HttpServletRequest req = (HttpServletRequest) pageContext
230: .getRequest();
231: if (!hasErrors()) {
232: if (TagConfig.isDefaultJavaScript()) {
233: if (_divState.id != null) {
234: ScriptRequestState srs = ScriptRequestState
235: .getScriptRequestState(req);
236: srs.mapTagId(getScriptReporter(), _divState.id,
237: _divState.id, null);
238: }
239: }
240: WriteRenderAppender writer = new WriteRenderAppender(
241: pageContext);
242: TagRenderingBase divRenderer = TagRenderingBase.Factory
243: .getRendering(TagRenderingBase.DIV_TAG, req);
244: divRenderer.doEndTag(writer);
245: }
246: localRelease();
247: return EVAL_PAGE;
248: }
249:
250: protected void localRelease() {
251: super .localRelease();
252: _tagId = null;
253: _divState.clear();
254: _firstPage = null;
255: _dataSource = null;
256: }
257:
258: /**
259: */
260: protected DivPanelState getState(ExpressionHandling expr)
261: throws JspException {
262: String datasource = "{" + _dataSource + "}";
263: Object state = expr.evaluateExpression(datasource,
264: "dataSource", pageContext);
265: if (state == null || hasErrors()) {
266: return null;
267: }
268:
269: if (!(state instanceof DivPanelState)) {
270: String s = Bundle.getString(
271: "Tags_DivPanelInvalidAttribute", _dataSource);
272: registerTagError(s, null);
273: return null;
274: }
275: return (DivPanelState) state;
276: }
277: }
|