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.context.effects;
035:
036: import com.icesoft.faces.context.DOMContext;
037: import com.icesoft.faces.renderkit.dom_html_basic.HTML;
038: import org.apache.commons.logging.Log;
039: import org.apache.commons.logging.LogFactory;
040: import org.w3c.dom.Element;
041:
042: import javax.faces.component.UIComponent;
043: import javax.faces.context.FacesContext;
044: import javax.faces.el.ValueBinding;
045: import javax.servlet.http.HttpServletRequest;
046: import java.util.HashMap;
047: import java.util.Map;
048:
049: /**
050: * Effects can change a components style. This class keeps track of these
051: * changes
052: */
053: public class CurrentStyle {
054:
055: /**
056: * Name of field used to send CSS Updated
057: */
058: public static String CSS_UPDATE_FIELD = "icefacesCssUpdates";
059: /**
060: * String uploaded
061: */
062: private String cssString;
063:
064: /**
065: * Last string uplodaed
066: */
067: private String lastCssString;
068:
069: /**
070: * Constant for visible = true
071: */
072: private static String DISPLAY_ON = "display:block;";
073:
074: /**
075: * Constant for visible =false
076: */
077: private static String DISPLAY_OFF = "display:none;";
078:
079: private static final Log log = LogFactory
080: .getLog(CurrentStyle.class);
081:
082: /**
083: * @param cssString
084: */
085: public CurrentStyle(String cssString) {
086: this .cssString = cssString;
087: }
088:
089: public String getCssString() {
090: return cssString;
091: }
092:
093: public String getLastCssString() {
094: return lastCssString;
095: }
096:
097: public void setLastCssString(String lastCssString) {
098: this .lastCssString = lastCssString;
099: }
100:
101: /**
102: * Apply CSS changes to the rendered componenent
103: *
104: * @param facesContext
105: * @param uiComponent
106: */
107: public static void apply(FacesContext facesContext,
108: UIComponent uiComponent) {
109: apply(facesContext, uiComponent, null, null);
110: }
111:
112: /**
113: * Apply css changes to rendered component
114: *
115: * @param facesContext
116: * @param uiComponent
117: * @param targetElement
118: * @param style
119: */
120: public static void apply(FacesContext facesContext,
121: UIComponent uiComponent, Element targetElement, String style) {
122: if (targetElement == null) {
123: DOMContext domContext = DOMContext.getDOMContext(
124: facesContext, uiComponent);
125: Object node = domContext.getRootNode();
126: if (node == null || !(node instanceof Element)) {
127: return;
128: }
129: Element root = (Element) node;
130: targetElement = root;
131: }
132: String jspStyle = (String) uiComponent.getAttributes().get(
133: "style");
134: if (log.isTraceEnabled()) {
135: if (jspStyle != null) {
136: log.trace("Existing style [" + jspStyle + "]");
137: }
138: }
139:
140: if (style != null) {
141: if (jspStyle == null) {
142: jspStyle = "";
143: }
144: jspStyle += style;
145: }
146:
147: Boolean visibility = (Boolean) uiComponent.getAttributes().get(
148: "visible");
149: // default to true if visibility is null
150: boolean visible = true;
151: if (visibility != null) {
152: visible = visibility.booleanValue();
153: }
154: CurrentStyle currentStyle = (CurrentStyle) uiComponent
155: .getAttributes().get("currentStyle");
156: if (currentStyle != null) {
157: String appendedStyle = currentStyle.cssString;
158:
159: currentStyle.lastCssString = currentStyle.cssString;
160: if (appendedStyle != null) {
161: if (jspStyle == null) {
162: jspStyle = appendedStyle;
163: } else {
164: jspStyle += ";" + appendedStyle;
165: }
166: }
167:
168: }
169:
170: if (visible) {
171: if (jspStyle != null) {
172: int startI = jspStyle.indexOf(DISPLAY_OFF);
173: if (startI != -1) {
174: String start = "";
175: if (startI > 0) {
176: start = jspStyle.substring(0, startI);
177: }
178: int endI = startI + DISPLAY_OFF.length();
179: String end = "";
180: if (endI < jspStyle.length()) {
181: end = jspStyle.substring(endI);
182: }
183: jspStyle = start + end;
184: }
185: }
186: } else {
187:
188: if (jspStyle == null) {
189: jspStyle = DISPLAY_OFF;
190: } else {
191: jspStyle += DISPLAY_OFF;
192: }
193: }
194: if (log.isTraceEnabled()) {
195: if (jspStyle != null) {
196: log.trace("JSP Style [" + jspStyle + "]");
197: }
198: }
199: if (targetElement != null) {
200: if (jspStyle != null && jspStyle.length() > 0)
201: targetElement.setAttribute(HTML.STYLE_ATTR, jspStyle);
202: else
203: targetElement.removeAttribute(HTML.STYLE_ATTR);
204: }
205: }
206:
207: /**
208: * Parse cssUpdates from browser. Format id{property:value;property;value}id{property:value}
209: *
210: */
211: public static Map decode(FacesContext facesContext) {
212:
213: Map parameters = facesContext.getExternalContext()
214: .getRequestParameterMap();
215: String cssUpdate = (String) parameters.get(CSS_UPDATE_FIELD);
216: Map requestMap = facesContext.getExternalContext()
217: .getRequestMap();
218: String oldCssUpdate = (String) requestMap.get(CSS_UPDATE_FIELD);
219:
220: if (cssUpdate == null || cssUpdate.length() == 0) {
221: return null;
222: }
223: Map updates = null;
224: if (!cssUpdate.equals(oldCssUpdate)) {
225: updates = new HashMap();
226:
227: int rightBrace = 0;
228: do {
229: rightBrace = cssUpdate.indexOf("}");
230: if (rightBrace != -1) {
231: String update = cssUpdate
232: .substring(0, ++rightBrace);
233:
234: cssUpdate = cssUpdate.substring(rightBrace);
235: int leftBrace = update.indexOf("{");
236: String id = update.substring(0, leftBrace);
237:
238: leftBrace++;
239: String style = update.substring(leftBrace, update
240: .length() - 1);
241: if (log.isTraceEnabled()) {
242: log.trace("Adding id[" + id + "] Style ["
243: + style + "]");
244: }
245: updates.put(id, style);
246: }
247: } while (rightBrace != -1);
248: facesContext.getExternalContext().getSessionMap().put(
249: CurrentStyle.class.getName(), updates);
250: requestMap.put(CSS_UPDATE_FIELD, cssUpdate);
251: }
252: return updates;
253: }
254:
255: /**
256: * Parse CSS updates for a componenet
257: *
258: * @param facesContext
259: * @param uiComponent
260: */
261: public static void decode(FacesContext facesContext,
262: UIComponent uiComponent) {
263:
264: decode(facesContext);
265: Map map = (Map) facesContext.getExternalContext()
266: .getSessionMap().get(CurrentStyle.class.getName());
267: if (map == null) {
268: return;
269: }
270: if (uiComponent == null) {
271: return;
272: }
273: String clientId = uiComponent.getClientId(facesContext);
274: String style = (String) map.get(clientId);
275: if (style == null) {
276: return;
277: }
278:
279: if (log.isTraceEnabled()) {
280: log.trace("Decode Applying Style to [" + clientId
281: + "] Css [" + style + "]");
282: }
283: CurrentStyle cs = (CurrentStyle) uiComponent.getAttributes()
284: .get("currentStyle");
285: if (cs != null) {
286: cs.cssString = style;
287: } else {
288: cs = new CurrentStyle(style);
289:
290: uiComponent.getAttributes().put("currentStyle",
291: new CurrentStyle(style));
292: }
293:
294: // sync the component visible attribute with the css display style attribute
295: Boolean value = Boolean.valueOf("true");
296: if (cs.cssString.endsWith(DISPLAY_OFF)) {
297: value = Boolean.valueOf("false");
298: }
299: ValueBinding vb = uiComponent.getValueBinding("visible");
300: if (vb == null) {
301: uiComponent.getAttributes().put("visible", value);
302: } else {
303: try {
304: vb.setValue(facesContext, value);
305: } catch (Exception e) {
306:
307: if (log.isErrorEnabled()) {
308: log
309: .error(
310: "Exception setting visible. Value Binding ["
311: + vb.getExpressionString()
312: + "]", e);
313: if (facesContext == null) {
314: log.error("Faces Context is null");
315: }
316: }
317: }
318: }
319: }
320:
321: }
|