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;
020:
021: import org.apache.beehive.netui.util.internal.InternalStringBuilder;
022: import org.apache.beehive.netui.util.internal.ServletUtils;
023:
024: //import org.apache.beehive.netui.pageflow.util.URLRewriterService;
025: import org.apache.beehive.netui.tags.html.Html;
026: import org.apache.beehive.netui.tags.javascript.IScriptReporter;
027: import org.apache.beehive.netui.tags.javascript.ScriptContainer;
028: import org.apache.beehive.netui.util.Bundle;
029: import org.apache.beehive.netui.util.logging.Logger;
030: import org.apache.beehive.netui.core.urls.URLRewriterService;
031: import org.apache.beehive.netui.pageflow.internal.InternalUtils;
032: import org.apache.struts.Globals;
033: import org.apache.struts.util.RequestUtils;
034:
035: import javax.servlet.ServletRequest;
036: import javax.servlet.http.HttpServletRequest;
037: import javax.servlet.jsp.JspContext;
038: import javax.servlet.jsp.JspException;
039: import javax.servlet.jsp.JspWriter;
040: import javax.servlet.jsp.PageContext;
041: import javax.servlet.jsp.tagext.*;
042: import java.io.IOException;
043: import java.io.StringWriter;
044: import java.io.Writer;
045: import java.util.Locale;
046: import java.util.ArrayList;
047:
048: /**
049: * @netui:tag
050: */
051: public abstract class AbstractSimpleTag extends SimpleTagSupport
052: implements INetuiTag {
053: private static final Logger logger = Logger
054: .getInstance(AbstractSimpleTag.class);
055: private ErrorHandling _eh; // This class will track and handle errors
056:
057: /**
058: * Return the name of the tag. Used by error reporting to get the name of the tag.
059: * @return the name of the tag.
060: */
061: public abstract String getTagName();
062:
063: /**
064: * @param trim
065: * @return String
066: * @throws JspException
067: * @throws IOException
068: */
069: protected String getBufferBody(boolean trim) throws JspException,
070: IOException {
071: Writer body = new StringWriter(32);
072: JspFragment frag = getJspBody();
073: if (frag == null)
074: return null;
075: frag.invoke(body);
076: String text = body.toString();
077: if (trim && text != null)
078: text = text.trim();
079: return (text.length() == 0) ? null : text;
080: }
081:
082: /**
083: * Report an error if the value of <code>attrValue</code> is equal to the empty string, otherwise return
084: * that value. If <code>attrValue</code> is equal to the empty string, an error is registered and
085: * null is returned.
086: * @param attrValue The value to be checked for the empty string
087: * @param attrName The name of the attribute
088: * @return either the attrValue if it is not the empty string or null
089: * @throws JspException A JspException will be thrown if inline error reporting is turned off.
090: */
091: protected final String setRequiredValueAttribute(String attrValue,
092: String attrName) throws JspException {
093: assert (attrValue != null) : "parameter '" + attrValue
094: + "' must not be null";
095: assert (attrName != null) : "parameter '" + attrName
096: + "' must not be null";
097:
098: if ("".equals(attrValue)) {
099: String s = Bundle.getString("Tags_AttrValueRequired",
100: new Object[] { attrName });
101: registerTagError(s, null);
102: return null;
103: }
104: return attrValue;
105: }
106:
107: /**
108: * Filter out the empty string value and return either the value or null. When the value of
109: * <code>attrValue</code> is equal to the empty string this will return null, otherwise it will
110: * return the value of <code>attrValue</code>.
111: * @param attrValue This is the value we will check for the empty string.
112: * @return either the value of attrValue or null
113: */
114: protected final String setNonEmptyValueAttribute(String attrValue) {
115: return ("".equals(attrValue)) ? null : attrValue;
116: }
117:
118: /**
119: * This method will return the user local of the request.
120: * @return the Locale object to use when rendering this tag
121: */
122: protected Locale getUserLocale() {
123: return InternalUtils.lookupLocale(getJspContext());
124: }
125:
126: /**
127: * This method will attempt to cast the JspContext into a PageContext. If this fails,
128: * it will log an exception.
129: * @return PageContext
130: */
131: protected PageContext getPageContext() {
132: JspContext ctxt = getJspContext();
133: if (ctxt instanceof PageContext)
134: return (PageContext) ctxt;
135:
136: // assert the page context and log an error in production
137: assert (false) : "The JspContext was not a PageContext";
138: logger.error("The JspContext was not a PageContext");
139: return null;
140: }
141:
142: /**
143: * This mehod will write the passed string to the response.
144: * @param string to be written to the response.
145: */
146: protected final void write(String string) throws JspException {
147: JspContext ctxt = getJspContext();
148: JspWriter writer = ctxt.getOut();
149: try {
150: writer.print(string);
151: } catch (IOException e) {
152: logger.error(Bundle.getString("Tags_WriteException"), e);
153: if (ctxt instanceof PageContext)
154: RequestUtils.saveException((PageContext) ctxt, e);
155: JspException jspException = new JspException(
156: e.getMessage(), e);
157:
158: // todo: future cleanup
159: // The 2.5 Servlet api will set the initCause in the Throwable superclass during construction,
160: // this will cause an IllegalStateException on the following call.
161: if (jspException.getCause() == null) {
162: jspException.initCause(e);
163: }
164: throw jspException;
165: }
166: }
167:
168: /**
169: * This will report an error from a tag. The error will
170: * contain a message. If error reporting is turned off,
171: * the message will be returned and the caller should throw
172: * a JspException to report the error.
173: * @param message - the message to register with the error
174: * @throws javax.servlet.jsp.JspException - if in-page error reporting is turned off this method will always
175: * throw a JspException.
176: */
177: public void registerTagError(String message, Throwable e)
178: throws JspException {
179: ErrorHandling eh = getErrorHandling();
180: eh.registerTagError(message, getTagName(), this , e);
181: }
182:
183: public void registerTagError(AbstractPageError error)
184: throws JspException {
185: ErrorHandling eh = getErrorHandling();
186: eh.registerTagError(error, this );
187: }
188:
189: /**
190: * This method will return <code>true</code> if there have been any errors registered on this
191: * tag. Otherwise it returns <code>false</code>
192: * @return <code>true</code> if errors have been reported on this tag.
193: */
194: protected boolean hasErrors() {
195: return (_eh != null);
196: }
197:
198: /**
199: * This method will write out the <code>String</code> returned by <code>getErrorsReport</code> to the
200: * response output stream.
201: * @throws JspException if <code>write</code> throws an exception.
202: * @see #write
203: */
204: protected void reportErrors() throws JspException {
205: assert (_eh != null);
206: String err = _eh.getErrorsReport(getTagName());
207: IErrorCollector ec = (IErrorCollector) SimpleTagSupport
208: .findAncestorWithClass(this , IErrorCollector.class);
209: if (ec != null) {
210: ec.collectChildError(err);
211: } else {
212: write(err);
213: }
214: }
215:
216: protected String getInlineError() {
217: return _eh.getInlineError(getTagName());
218: }
219:
220: /**
221: * This method will return an ErrorHandling instance.
222: * @return Return the error handler
223: */
224: private ErrorHandling getErrorHandling() {
225: if (_eh == null) {
226: _eh = new ErrorHandling();
227: }
228: return _eh;
229: }
230:
231: /**
232: * Return the closest <code>ScriptReporter</code> in the parental chain. Searching starts
233: * at this node an moves upward through the parental chain.
234: * @return a <code>ScriptReporter</code> or null if there is not one found.
235: */
236: protected IScriptReporter getScriptReporter() {
237: IScriptReporter sr = (IScriptReporter) SimpleTagSupport
238: .findAncestorWithClass(this , IScriptReporter.class);
239: return sr;
240: }
241:
242: /**
243: * This method will return the scriptReporter that is represented by the HTML tag.
244: * @return IScriptReporter
245: */
246: protected IScriptReporter getHtmlTag(ServletRequest req) {
247: Html html = (Html) req.getAttribute(Html.HTML_TAG_ID);
248: if (html != null && html instanceof IScriptReporter)
249: return (IScriptReporter) html;
250: return null;
251: }
252:
253: /**
254: * This method will rewrite the name (id) by passing it to the
255: * URL Rewritter and getting back a value.
256: * @param name the name that will be rewritten
257: * @return a name that has been rewritten by the URLRewriterService.
258: */
259: final protected String rewriteName(String name) {
260: PageContext pageContext = getPageContext();
261: return URLRewriterService.getNamePrefix(pageContext
262: .getServletContext(), pageContext.getRequest(), name)
263: + name;
264: }
265:
266: /**
267: * This method will generate a real id based upon the passed in tagId. The generated
268: * id will be constucted by searching upward for all the script containers that have a
269: * scope id set. These will form a fully qualified id.
270: * @param tagId The base tagId set on a tag
271: * @return an id value formed by considering all of the scope id's found in the tag hierarchy.
272: */
273: final protected String getIdForTagId(String tagId) {
274: HttpServletRequest req = (HttpServletRequest) getPageContext()
275: .getRequest();
276: ArrayList/*<String>*/list = (ArrayList/*<String>*/) org.apache.beehive.netui.tags.RequestUtils
277: .getOuterAttribute(req, ScriptContainer.SCOPE_ID);
278: if (list == null)
279: return tagId;
280: InternalStringBuilder sb = new InternalStringBuilder();
281: for (int i = 0; i < list.size(); i++) {
282: sb.append((String) list.get(i));
283: sb.append('.');
284: }
285: sb.append(tagId);
286: return sb.toString();
287: }
288: }
|