001: /*
002: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003: *
004: * "The contents of this file are subject to the Mozilla Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License at
007: * http://www.mozilla.org/MPL/
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
011: * License for the specific language governing rights and limitations under
012: * the License.
013: *
014: * The Original Code is ICEfaces 1.5 open source software code, released
015: * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
016: * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
017: * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
018: *
019: * Contributor(s): _____________________.
020: *
021: * Alternatively, the contents of this file may be used under the terms of
022: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
023: * License), in which case the provisions of the LGPL License are
024: * applicable instead of those above. If you wish to allow use of your
025: * version of this file only under the terms of the LGPL License and not to
026: * allow others to use your version of this file under the MPL, indicate
027: * your decision by deleting the provisions above and replace them with
028: * the notice and other provisions required by the LGPL License. If you do
029: * not delete the provisions above, a recipient may use your version of
030: * this file under either the MPL or the LGPL License."
031: *
032: */
033:
034: package com.icesoft.faces.component.outputprogress;
035:
036: import java.io.IOException;
037:
038: import javax.faces.FacesException;
039: import javax.faces.component.UIComponent;
040: import javax.faces.context.FacesContext;
041:
042: import org.w3c.dom.Element;
043: import org.w3c.dom.Node;
044: import org.w3c.dom.Text;
045:
046: import com.icesoft.faces.component.CSS_DEFAULT;
047: import com.icesoft.faces.component.ext.taglib.Util;
048: import com.icesoft.faces.context.DOMContext;
049: import com.icesoft.faces.renderkit.dom_html_basic.DomBasicInputRenderer;
050: import com.icesoft.faces.renderkit.dom_html_basic.HTML;
051: import com.icesoft.faces.renderkit.dom_html_basic.PassThruAttributeRenderer;
052:
053: public class OutputProgressRenderer extends DomBasicInputRenderer {
054:
055: public void encodeEnd(FacesContext facesContext,
056: UIComponent uiComponent) throws IOException {
057:
058: validateParameters(facesContext, uiComponent,
059: OutputProgress.class);
060: DOMContext domContext = DOMContext.attachDOMContext(
061: facesContext, uiComponent);
062:
063: if (!domContext.isInitialized()) {
064: Element table = domContext
065: .createRootElement(HTML.TABLE_ELEM);
066: setRootElementId(facesContext, table, uiComponent);
067: table.setAttribute(HTML.CELLPADDING_ATTR, "0");
068: table.setAttribute(HTML.CELLSPACING_ATTR, "0");
069: table.setAttribute(HTML.BORDER_ATTR, "0");
070: }
071: Element table = (Element) domContext.getRootNode();
072: String style = ((OutputProgress) uiComponent).getStyle();
073: if (style != null && style.length() > 0)
074: table.setAttribute(HTML.STYLE_ATTR, style);
075: else
076: table.removeAttribute(HTML.STYLE_ATTR);
077: //In order to fix IRAPtor Bug 291, we took out buildLayout() from the intialized block,
078: //Because of variouse text position, layout could have different combination of tr and td
079: //therefore we are storing nodes to the component itself.
080: buildLayout(table, uiComponent, domContext);
081:
082: if (PassThruAttributeRenderer
083: .passThruAttributeExists(uiComponent)) {
084: PassThruAttributeRenderer.renderAttributes(facesContext,
085: uiComponent, null);
086: }
087:
088: domContext.stepOver();
089: domContext.streamWrite(facesContext, uiComponent);
090: }
091:
092: private void setPercentage(UIComponent uiComponent,
093: DOMContext domContext, Text percentageText, Element fillBar) {
094: String space = " ";
095: if (domContext.isStreamWriting()) {
096: space = "";
097: }
098:
099: OutputProgress progressBar = (OutputProgress) uiComponent;
100:
101: String progressLabel = progressBar.getProgressLabel();
102: int percentValue = progressBar.getValue();
103: if (percentValue > 100) {
104: percentValue = 100;
105: }
106: if (percentValue < 0) {
107: percentValue = 0;
108: }
109: //update percent value in determinate mode only
110: if (progressBar.getIndeterminate() == false) {
111: percentageText.setData(percentValue + " %");
112: }
113:
114: if (percentValue < 100) {
115:
116: if (progressLabel != null && progressLabel.length() > 0) {
117: percentageText.setData(progressLabel);
118: }
119: //following if block is for Indeterminate mode only
120: if (progressBar.getIndeterminate()) {
121: if (percentValue < 1) {
122: fillBar.setAttribute(HTML.CLASS_ATTR, progressBar
123: .getIndeterminateInactiveClass());
124: percentageText.setData(space);
125: } else {
126: fillBar.setAttribute(HTML.CLASS_ATTR, progressBar
127: .getIndeterminateActiveClass());
128: fillBar.setAttribute(HTML.STYLE_ATTR,
129: "position:absolute;width:100%");
130:
131: if (progressLabel != null
132: && progressLabel.length() > 0) {
133: percentageText.setData(progressLabel);
134: } else {
135: percentageText.setData(space);
136: }
137: }
138: }
139:
140: } else {
141: if (progressBar.getIndeterminate()) {
142: fillBar.setAttribute(HTML.CLASS_ATTR, progressBar
143: .getIndeterminateInactiveClass());
144: fillBar.setAttribute(HTML.STYLE_ATTR,
145: "position:absolute;width:100%;");
146: }
147: String progressCompleteLabel = progressBar
148: .getProgressLabelComplete();
149: if (progressCompleteLabel != null
150: && progressCompleteLabel.length() > 0) {
151: percentageText.setData(progressCompleteLabel);
152: }
153: }
154:
155: // The following fix is required for determinate mode only
156: if (progressBar.getIndeterminate() == false) {
157: // This code it to fix IE renderering. If a nbsp is present and the value is zero
158: // then a tiny bit of the bar is rendered. However if this value is missing then
159: // firefox will not render the bar. Therefore we don't add the nbsp until we
160: // need to render the bar
161: Node node = fillBar.getFirstChild();
162: if (node instanceof Text) {
163: if (percentValue <= 0) {
164: fillBar.removeChild(node);
165: }
166: } else if (node == null) {
167: if (percentValue > 0) {
168: Text nbsp4opera = domContext
169: .createTextNode(" ");
170: fillBar.appendChild(nbsp4opera);
171: }
172: }
173: }
174: //set the percent value for determinate mode only
175: if (progressBar.getIndeterminate() == false) {
176: fillBar.setAttribute(HTML.STYLE_ATTR,
177: "position:absolute;width:" + percentValue + "%;");
178: }
179: }
180:
181: private void buildLayout(Element table, UIComponent uiComponent,
182: DOMContext domContext) {
183: String space = " ";
184: if (domContext.isStreamWriting()) {
185: space = "";
186: }
187: Node node = table.getFirstChild();
188: Element tbody = domContext.createElement(HTML.TBODY_ELEM);
189: if (node != null) {
190: table.replaceChild(tbody, node);
191: } else {
192: table.appendChild(tbody);
193: }
194:
195: OutputProgress progressBar = (OutputProgress) uiComponent;
196: table
197: .setAttribute(HTML.CLASS_ATTR, progressBar
198: .getStyleClass());
199:
200: Element row = domContext.createElement(HTML.TR_ELEM);
201: Element textTd = domContext.createElement(HTML.TD_ELEM);
202: textTd
203: .setAttribute(HTML.CLASS_ATTR, progressBar
204: .getTextClass());
205:
206: Element barTd = domContext.createElement(HTML.TD_ELEM);
207: tbody.appendChild(row);
208: Text percentageText = null;
209: if (progressBar.getProgressLabel() != null) {
210: //add the blank label initially
211: percentageText = domContext.createTextNode(space);
212: } else {
213: percentageText = domContext.createTextNode("0 %");
214: }
215:
216: textTd.appendChild(percentageText);
217: textTd.setAttribute("id", uiComponent.getClientId(FacesContext
218: .getCurrentInstance())
219: + "percentageText");
220:
221: Element bgBar = domContext.createElement(HTML.DIV_ELEM);
222: bgBar.setAttribute(HTML.CLASS_ATTR, progressBar
223: .getBackgroundClass());
224: bgBar.setAttribute(HTML.STYLE_ATTR, "position:relative;");
225:
226: Element fillBar = domContext.createElement(HTML.DIV_ELEM);
227: fillBar.setAttribute(HTML.ID_ATTR, uiComponent
228: .getClientId(FacesContext.getCurrentInstance())
229: + "bar");
230:
231: if (progressBar.getIndeterminate() == false) { //determinate mode
232: fillBar.setAttribute(HTML.CLASS_ATTR, progressBar
233: .getFillClass());
234: fillBar.setAttribute(HTML.STYLE_ATTR,
235: "position:absolute;width:0%");
236: } else {// indeterminate mode
237: fillBar.setAttribute(HTML.CLASS_ATTR, progressBar
238: .getIndeterminateInactiveClass());
239: fillBar.setAttribute(HTML.STYLE_ATTR,
240: "position:absolute;width:100%;");
241: }
242:
243: bgBar.appendChild(fillBar);
244: Text nbsp4mozila = domContext.createTextNode(space);
245:
246: barTd.appendChild(bgBar);
247:
248: String textPosition = progressBar.getLabelPosition();
249:
250: if (!isValidTextPosition(textPosition.toString().toLowerCase())) {
251: throw new FacesException(
252: "Please define valid textPosition [top|bottom|left|right|topcenter|bottomcenter|topright|bottomright|embed]");
253: }
254:
255: if (textPosition.toString().equalsIgnoreCase("left")) {
256: textTd.setAttribute("style", "vertical-align: middle;");
257: row.appendChild(textTd);
258: row.appendChild(barTd);
259: }
260: if (textPosition.toString().equalsIgnoreCase("right")) {
261: textTd.setAttribute("style", "vertical-align: middle;");
262: row.appendChild(barTd);
263: row.appendChild(textTd);
264: }
265:
266: if (textPosition.toString().toLowerCase().startsWith("top")) {
267: Element row2 = domContext.createElement(HTML.TR_ELEM);
268: row.appendChild(textTd);
269: row2.appendChild(barTd);
270: tbody.appendChild(row2);
271: if (textPosition.toString().equalsIgnoreCase("topcenter")) {
272: textTd.setAttribute("align", "center");
273: }
274: if (textPosition.toString().equalsIgnoreCase("topright")) {
275: textTd.setAttribute("align", "right");
276: }
277: }
278:
279: if (textPosition.toString().toLowerCase().startsWith("bottom")) {
280: Element row2 = domContext.createElement(HTML.TR_ELEM);
281: row.appendChild(barTd);
282: row2.appendChild(textTd);
283: tbody.appendChild(row2);
284: if (textPosition.toString()
285: .equalsIgnoreCase("bottomcenter")) {
286: textTd.setAttribute("align", "center");
287: }
288: if (textPosition.toString().equalsIgnoreCase("bottomright")) {
289: textTd.setAttribute("align", "right");
290: }
291: }
292:
293: if (textPosition.toString().equalsIgnoreCase("embed")) {
294: Element embedDiv = domContext.createElement(HTML.DIV_ELEM);
295: embedDiv.setAttribute(HTML.CLASS_ATTR, progressBar
296: .getTextClass());
297: embedDiv
298: .setAttribute(
299: HTML.STYLE_ATTR,
300: "text-align:center;position:relative;background-color:transparent;width:100%;z-index:1;");
301: embedDiv.appendChild(percentageText);
302:
303: if (progressBar.getIndeterminate() == false) {//determinate mode
304: bgBar.appendChild(embedDiv);
305: } else {//indeterminate mode
306: fillBar.appendChild(embedDiv);
307: }
308: row.appendChild(barTd);
309: } else {
310: //  fix for mozila
311: Text nbsp4opera = domContext.createTextNode(space);
312: //  fix for opera
313: fillBar.appendChild(nbsp4opera);
314: bgBar.appendChild(nbsp4mozila);
315: }
316:
317: setPercentage(uiComponent, domContext, percentageText, fillBar);
318: }
319:
320: private boolean isValidTextPosition(String textPosition) {
321: String[] validPosition = { "top", "bottom", "left", "right",
322: "topcenter", "bottomcenter", "topright", "bottomright",
323: "embed" };
324: for (int i = 0; i < validPosition.length; i++) {
325: if (validPosition[i].equals(textPosition)) {
326: return true;
327: }
328: }
329: return false;
330: }
331: }
|