001: /**
002: * Copyright 2007 Webmedia Group Ltd.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: **/package org.araneaframework.jsp.tag.uilib.tab;
016:
017: import java.io.IOException;
018: import java.io.Writer;
019: import java.util.ArrayList;
020: import java.util.Collection;
021: import java.util.Iterator;
022: import java.util.List;
023: import javax.servlet.jsp.JspException;
024: import org.araneaframework.core.Assert;
025: import org.araneaframework.jsp.UiEvent;
026: import org.araneaframework.jsp.UiUpdateEvent;
027: import org.araneaframework.jsp.exception.AraneaJspException;
028: import org.araneaframework.jsp.tag.PresentationTag;
029: import org.araneaframework.jsp.tag.StyledTagInterface;
030: import org.araneaframework.jsp.tag.include.WidgetIncludeTag;
031: import org.araneaframework.jsp.tag.uilib.BaseWidgetTag;
032: import org.araneaframework.jsp.tag.updateregion.UpdateRegionHtmlTag;
033: import org.araneaframework.jsp.util.JspUtil;
034: import org.araneaframework.jsp.util.JspWidgetCallUtil;
035: import org.araneaframework.uilib.tab.TabContainerWidget;
036: import org.araneaframework.uilib.tab.TabWidget;
037: import org.araneaframework.uilib.util.NameUtil;
038:
039: /**
040: * @jsp.tag
041: * name = "tabContainer"
042: * body-content = "JSP"
043: * description = "Writes out tabs' labels. Content should include <ui:tabBody> tag."
044: *
045: * @author Nikita Salnikov-Tarnovski (<a href="mailto:nikem@webmedia.ee">nikem@webmedia.ee</a>)
046: * @author Taimo Peelo (taimo@araneaframework.org)
047: *
048: * @see TabContainerWidget
049: *
050: * @since 1.1
051: */
052: public class TabContainerHtmlTag extends BaseWidgetTag implements
053: StyledTagInterface {
054: protected String style = null;
055: protected String styleClass = null;
056: protected String baseStyleClass = "aranea-tabs";
057: protected boolean registerUpdateRegions = false;
058: protected UpdateRegionHtmlTag updateRegionTag;
059:
060: /** Context entry key for {@link TabContainerWidget} rendered by this tag. */
061: public static final String TAB_CONTAINER_WIDGET = "tabContainerWidget";
062: public static final String TAB_CONTAINER_UPDATE_REGION_NAME = "tcur";
063:
064: public static final String TAB_CLASS_SELECTED = "aranea-active-tab";
065: public static final String TAB_CLASS_PASSIVE = null;
066: public static final String TAB_CLASS_DISABLED = "aranea-disabled-tab";
067:
068: public static final String TAB_LINK_CLASS = "aranea-tab-link";
069:
070: public int doStartTag(Writer out) throws Exception {
071: super .doStartTag(out);
072: Assert
073: .isInstanceOf(TabContainerWidget.class, widget,
074: "<ui:tabContainer> must be used only for referring to TabContainerWidget");
075: addContextEntry(TAB_CONTAINER_WIDGET, widget);
076:
077: // optionally write out update region tag start
078: writeUpdateRegionStart();
079:
080: // WRITE OUT TABS
081: writeTabsDivStart(out);
082:
083: TabContainerWidget tabContainerWidget = (TabContainerWidget) widget;
084:
085: Collection tabs = tabContainerWidget.getTabs().values();
086:
087: for (Iterator i = tabs.iterator(); i.hasNext();) {
088: TabWidget tabwidget = (TabWidget) i.next();
089: writeTab(out, tabwidget);
090: }
091:
092: writeClearanceDiv(out);
093: writeTabsDivEnd(out);
094:
095: return EVAL_BODY_INCLUDE;
096: }
097:
098: protected void writeTab(Writer out, TabWidget tabwidget)
099: throws Exception {
100: JspUtil.writeOpenStartTag(out, "div");
101: JspUtil.writeAttribute(out, "class",
102: getTabStyleClass(tabwidget));
103: JspUtil.writeCloseStartTag_SS(out);
104:
105: writeTablink(out, tabwidget);
106:
107: JspUtil.writeEndTag(out, "div");
108: }
109:
110: protected int doEndTag(Writer out) throws Exception {
111: writeUpdateRegionEnd();
112: return super .doEndTag(out);
113: }
114:
115: protected void writeUpdateRegionStart() throws JspException {
116: if (registerUpdateRegions) {
117: updateRegionTag = new UpdateRegionHtmlTag();
118: registerSubtag(updateRegionTag);
119: updateRegionTag.setGlobalId(NameUtil.getFullName(fullId,
120: TAB_CONTAINER_UPDATE_REGION_NAME));
121: executeStartSubtag(updateRegionTag);
122: }
123: }
124:
125: protected void writeUpdateRegionEnd() throws JspException {
126: if (registerUpdateRegions) {
127: executeEndTagAndUnregister(updateRegionTag);
128: }
129: updateRegionTag = null;
130: }
131:
132: protected void writeClearanceDiv(Writer out) throws Exception {
133: out.write("<div class=\"aranea-clear\"> </div>");
134: }
135:
136: protected void writeTablink(Writer out, TabWidget tab)
137: throws Exception {
138: JspUtil.writeStartTag(out, "div");
139: writeTabLabel(out, tab);
140: JspUtil.writeEndTag(out, "div");
141: }
142:
143: protected void writeTabLabel(Writer out, TabWidget tab)
144: throws Exception {
145: if (tab.getLabel() != null) {
146: renderTabTextLabel(out, tab);
147: } else if (tab.getLabelWidget() != null) {
148: renderTabWidgetLabel(out, tab);
149: } else {
150: throw new AraneaJspException(
151: "Unable to determine label or labelwidget for TabWidget '"
152: + tab.getScope().toString() + "'.");
153: }
154: }
155:
156: protected void renderTabWidgetLabel(Writer out, TabWidget tab)
157: throws Exception {
158: String labelWidgetFullId = tab.getLabelWidget().getScope()
159: .toString();
160: String contextWidgetFullId = getContextWidgetFullId();
161:
162: if (labelWidgetFullId.startsWith(contextWidgetFullId)) {
163: WidgetIncludeTag includeTag = new WidgetIncludeTag();
164: String labelWidgetRelativeId = labelWidgetFullId
165: .substring(contextWidgetFullId.length());
166: includeTag.setId(labelWidgetRelativeId);
167: registerAndExecuteStartTag(includeTag);
168: executeEndTagAndUnregister(includeTag);
169: } else {
170: throw new AraneaJspException(
171: "Unable to determine id of labelWidget '"
172: + labelWidgetFullId
173: + "' relative to contextwidget '"
174: + contextWidgetFullId + "'.");
175: }
176: }
177:
178: protected void renderTabTextLabel(Writer out, TabWidget tab)
179: throws Exception {
180: if (tab.isTabDisabled()) {
181: renderDisabledTabTextLabel(out, tab);
182: } else {
183: renderEnabledTabTextLabel(out, tab);
184: }
185: }
186:
187: protected void renderEnabledTabTextLabel(Writer out, TabWidget tab)
188: throws IOException {
189: JspUtil.writeOpenStartTag(out, "a");
190: JspUtil.writeAttribute(out, "href", "#");
191: JspUtil.writeAttribute(out, "class", TAB_LINK_CLASS);
192:
193: UiEvent event = getTabSelectionEvent(tab);
194: JspUtil.writeEventAttributes(out, event);
195: JspWidgetCallUtil.writeSubmitScriptForEvent(out, "onclick");
196:
197: JspUtil.writeCloseStartTag_SS(out);
198: JspUtil.writeEscaped(out, tab.getLabel());
199: JspUtil.writeEndTag_SS(out, "a");
200: }
201:
202: protected void renderDisabledTabTextLabel(Writer out, TabWidget tab)
203: throws IOException {
204: JspUtil.writeOpenStartTag(out, "a");
205: JspUtil.writeCloseStartTag_SS(out);
206: JspUtil.writeEscaped(out, tab.getLabel());
207: JspUtil.writeEndTag(out, "a");
208: }
209:
210: protected UiEvent getTabSelectionEvent(TabWidget tab) {
211: UiUpdateEvent result;
212: if (registerUpdateRegions) {
213: List updateRegionNames = new ArrayList(1);
214: updateRegionNames.add(NameUtil.getFullName(fullId,
215: TAB_CONTAINER_UPDATE_REGION_NAME));
216: result = new UiUpdateEvent(
217: TabContainerWidget.TAB_SELECT_EVENT_ID, fullId, tab
218: .getScope().getId().toString(),
219: updateRegionNames);
220: } else {
221: result = new UiUpdateEvent(
222: TabContainerWidget.TAB_SELECT_EVENT_ID, fullId, tab
223: .getScope().getId().toString());
224: }
225: return result;
226: }
227:
228: protected String getTabStyleClass(TabWidget tabwidget) {
229: return tabwidget.isSelected() ? TAB_CLASS_SELECTED : tabwidget
230: .isTabDisabled() ? TAB_CLASS_DISABLED
231: : TAB_CLASS_PASSIVE;
232: }
233:
234: protected void writeTabsDivEnd(Writer out) throws Exception {
235: JspUtil.writeEndTag(out, "div");
236: }
237:
238: protected void writeTabsDivStart(Writer out) throws Exception {
239: JspUtil.writeOpenStartTag(out, "div");
240: JspUtil.writeAttribute(out, "class", getStyleClass());
241: JspUtil.writeCloseStartTag(out);
242: }
243:
244: /* ************************* StyledTagInterface ************************** */
245: /**
246: * @jsp.attribute
247: * type = "java.lang.String"
248: * required = "false"
249: * description = "Inline style for HTML tag."
250: */
251: public void setStyle(String style) throws JspException {
252: this .style = (String) evaluate("style", style, String.class);
253: }
254:
255: /**
256: * @jsp.attribute
257: * type = "java.lang.String"
258: * required = "false"
259: * description = "CSS class for tag"
260: */
261: public void setStyleClass(String styleClass) throws JspException {
262: if (styleClass != null)
263: this .styleClass = (String) evaluate("styleClass",
264: styleClass, String.class);
265: }
266:
267: protected String getStyleClass() {
268: return PresentationTag.calculateStyleClass(baseStyleClass,
269: styleClass);
270: }
271:
272: /**
273: * @jsp.attribute
274: * type = "java.lang.String"
275: * required = "false"
276: * description = "Boolean specifying whether the tab selection events should invoke partial render or full render. Default is false (full render)."
277: */
278: public void setRegisterUpdateRegions(String registerUpdateRegions)
279: throws JspException {
280: this .registerUpdateRegions = ((Boolean) evaluate(
281: "registerUpdateRegions", registerUpdateRegions,
282: Boolean.class)).booleanValue();
283: }
284: }
|