/* * $Id: IWBaseComponent.java,v 1.23 2009/03/12 01:59:46 idegaweb Exp $ * Created on 20.2.2004 by Tryggvi Larusson in project com.project * * Copyright (C) 2004 Idega. All Rights Reserved. * * This software is the proprietary information of Idega. * Use is subject to license terms. * */ package com.idega.presentation; import java.io.IOException; import java.util.List; import java.util.Locale; import java.util.logging.Logger; import javax.el.ELContext; import javax.el.ValueExpression; import javax.faces.component.UIComponent; import javax.faces.component.UIComponentBase; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; import org.springframework.beans.factory.annotation.Autowired; import com.idega.core.cache.CacheableUIComponent; import com.idega.core.cache.UIComponentCacher; import com.idega.idegaweb.IWBundle; import com.idega.idegaweb.IWMainApplication; import com.idega.idegaweb.IWResourceBundle; import com.idega.idegaweb.IWUserContext; import com.idega.util.CoreUtil; import com.idega.util.RenderUtils; import com.idega.util.WebUtil; import com.idega.util.expression.ELUtil; import com.idega.util.text.TextStyler; /** * <p> * This is a base UI component for JSF that adds extended functionality for idegaWeb.<br/> * This is supposed to be a convenient replacement for PresentationObject for new * pure JSF solutions and doesn't have the some of the legacy burdens that PresentationObject has * such as the old style idegaWeb main(IWContext) and print(IWContext) methods and event systems. * </p> * Copyright (C) idega software 2004-2006 <br/> * Last modified: $Date: 2009/03/12 01:59:46 $ by $Author: idegaweb $ * * @author <a href="mailto:tryggvi@idega.is">Tryggvi Larusson</a> * @version $Revision: 1.23 $ * */ public class IWBaseComponent extends UIComponentBase implements CacheableUIComponent { protected static Logger LOGGER = null; protected static final String divTag = "div"; protected static final String renderedAtt = "rendered"; public static final String EXPRESSION_BEGIN = "#{"; public static final String EXPRESSION_END = "}"; private TextStyler _styler; private String styleAttribute; private boolean isInitialized = false; private long iSystemTime = 0; protected Logger getLogger() { if (LOGGER == null) LOGGER = Logger.getLogger(getClass().getName()); return LOGGER; } protected Page getParentPage() { return getPage(this); } private Page getPage(UIComponent parent) { if (parent == null) { return null; } if (parent instanceof Page) { return (Page) parent; } return getPage(parent.getParent()); } /** * This is an old idegaWeb style add method. * Does the same as getChildren().add(comp) in JSF> * @param comp */ public void add(UIComponent comp){ getChildren().add(comp); } /* (non-Javadoc) * @see javax.faces.component.UIComponent#decode(javax.faces.context.FacesContext) */ @Override public void decode(FacesContext arg0) { super.decode(arg0); } /* (non-Javadoc) * @see javax.faces.component.UIComponent#processDecodes(javax.faces.context.FacesContext) */ @Override public void processDecodes(FacesContext arg0) { super.processDecodes(arg0); } /* (non-Javadoc) * @see javax.faces.component.UIComponent#encodeBegin(javax.faces.context.FacesContext) */ @Override public void encodeBegin(FacesContext context) throws IOException { CoreUtil.doEnsureScopeIsSet(context); UIComponentCacher cacher = getCacher(context); if(cacher.existsInCache(this,context)){ // do nothing: } else{ if(cacher.isCacheEnbled(this,context)){ cacher.beginCache(this,context); } this.iSystemTime = System.currentTimeMillis(); if(!isInitialized()){ initializeComponent(context); //TODO: Remove call to older method: initializeContent(); setInitialized(); } else{ updateComponent(context); } super.encodeBegin(context); } } /* (non-Javadoc) * @see javax.faces.component.UIComponent#encodeChildren(javax.faces.context.FacesContext) */ @Override public void encodeChildren(FacesContext context) throws IOException { /*if(getRendersChildren()){ Iterator children = this.getChildren().iterator(); while (children.hasNext()) { UIComponent element = (UIComponent) children.next(); renderChild(context,element); } }*/ /*Iterator children = this.getChildren().iterator(); while (children.hasNext()) { UIComponent element = (UIComponent) children.next(); renderChild(context,element); }*/ UIComponentCacher cacher = getCacher(context); if(cacher.existsInCache(this,context)){ // do nothing: } else{ super.encodeChildren(context); } } /** * <p> * Renders a child component for the current component. This operation is handy when implementing * renderes that perform child rendering themselves (eg. a layout renderer/grid renderer/ etc..). * Passes on any IOExceptions thrown by the child/child renderer. * </p> * @param context the current FacesContext * @param child which child to render */ public void renderChild(FacesContext context, UIComponent child) throws IOException { RenderUtils.renderChild(context,child); } /* (non-Javadoc) * @see javax.faces.component.UIComponent#encodeEnd(javax.faces.context.FacesContext) */ @Override public void encodeEnd(FacesContext context) throws IOException { UIComponentCacher cacher = getCacher(context); if(cacher.existsInCache(this,context)){ // encode the cached version: cacher.encodeCached(this,context); } else{ long endTime = System.currentTimeMillis(); String renderingText = (endTime - this.iSystemTime) + " ms"; context.getResponseWriter().writeComment(renderingText); super.encodeEnd(context); if(cacher.isCacheEnbled(this,context)){ cacher.endCache(this,context); } } } @Override public boolean getRendersChildren() { try { return super.getRendersChildren(); } catch (Exception e) { getLogger().warning("Error while resolving whether to render or not children (" + getChildren() + ") of " + getClass().getName()); } return false; } /** * * @uml.property name="styleAttribute" */ public void setStyleAttribute(String style) { if (this._styler == null) { this._styler = new TextStyler(); } this._styler.parseStyleString(style); this.styleAttribute = style; //this.set("style", _styler.getStyleString()); } public void setStyleAttribute(String attribute, String value) { if (this._styler == null) { this._styler = new TextStyler(); } this._styler.setStyleValue(attribute, value); setStyleAttribute( this._styler.getStyleString()); } /** * * @uml.property name="styleAttribute" */ public String getStyleAttribute() { return this.styleAttribute; } /* (non-Javadoc) * @see javax.faces.component.UIComponent#getFamily() */ @Override public String getFamily() { return "idegaweb"; } /** * <p> * This method was refactored and replaced with initializeComponent * </p> * @deprecated Replaced with initializeComponent */ @Deprecated protected void initializeContent() { //does nothing by default } /** * <p> * This is a method that is ensured that is only called once in initalization in a * state saved component. This method is intended to be implemented in subclasses for example to add components.<br/> * This method is called from the standard encodeBegin() method. * </p> * @param context the FacesContext for the request */ protected void initializeComponent(FacesContext context) { //does nothing by default } /** * <p> * This method is called when the component is already initialized (i.e. the second time and onwards when a faces rendering * is called upon this component when it is state saved) and usually happens when the component is restored after a "POST".<br/> * This callback method could be overrided in sublcasses if something is meant to happen when a new * request is sent on an already initialized component.<br/> * This method is called from the standard encodeBegin() method. * </p> * @param context */ protected void updateComponent(FacesContext context) { //Does nothing by default } /** * <p> * Returns if this component instance has been initialized, i.e. the initializeComponent() method called. * </p> * @return */ protected boolean isInitialized(){ return this.isInitialized; } protected void setInitialized(){ this.isInitialized=true; } protected void setInitialized(boolean initialized) { this.isInitialized = initialized; } /** * @see javax.faces.component.UIComponentBase#saveState(javax.faces.context.FacesContext) */ @Override public Object saveState(FacesContext ctx) { Object values[] = new Object[4]; values[0] = super.saveState(ctx); values[1] = this.styleAttribute; values[2] = this._styler; values[3] = new Boolean(this.isInitialized); return values; } /** * @see javax.faces.component.UIComponentBase#restoreState(javax.faces.context.FacesContext, * java.lang.Object) */ @Override public void restoreState(FacesContext ctx, Object state) { Object values[] = (Object[]) state; super.restoreState(ctx, values[0]); this.styleAttribute = ((String) values[1]); this._styler = (TextStyler) values[2]; this.isInitialized = ((Boolean) values[3]).booleanValue(); } /** * <p> * Get the IWMainapplication from the context * </p> * @param context * @return */ protected static IWMainApplication getIWMainApplication(FacesContext context){ return IWMainApplication.getIWMainApplication(context); } /** * <p> * Get the IWBundle from the bundleIdentifier. * </p> * @param context * @param bundleIdentifier * @return */ protected static IWBundle getIWBundle(FacesContext context,String bundleIdentifier){ IWMainApplication iwma = getIWMainApplication(context); return iwma.getBundle(bundleIdentifier); } /** * <p> * Get the IWResourceBundle from the context and bundleIdentifier. * It gets the locale from the context. * </p> * @param context * @param bundleIdentifier * @return */ protected static IWResourceBundle getIWResourceBundle(FacesContext context,String bundleIdentifier){ IWBundle bundle = getIWBundle(context,bundleIdentifier); Locale locale = null; UIViewRoot viewRoot = context.getViewRoot(); if(viewRoot!=null){ locale = viewRoot.getLocale(); } else{ locale = context.getExternalContext().getRequestLocale(); } return bundle.getResourceBundle(locale); } @Override public UIComponentCacher getCacher(FacesContext context){ return UIComponentCacher.getDefaultCacher(context); } /* (non-Javadoc) * @see com.idega.core.cache.CacheableUIComponent#getViewState(javax.faces.context.FacesContext) */ @Override public String getViewState(FacesContext context) { return "view"; } @Override public List<UIComponent> getChildren() { List<UIComponent> children = super.getChildren(); return children; } //@Override //public Map<Object, UIComponent> getFacets() { // Map<Object, UIComponent> facets = super.getFacets(); // return facets; //} /** * <p> * A method to check if the passed String is a valuebinding expression, * i.e. a string in the format '#{MyBeanId.myProperty}' * </p> * @param any String * @return */ public boolean isValueBinding(String value) { if (value == null) { return false; } int start = value.indexOf(EXPRESSION_BEGIN); if (start < 0) { return false; } int end = value.lastIndexOf(EXPRESSION_END); return (end >=0 && start < end); } /** * Creates the expression syntax, i.e. wraps the beanReference String around with #{ and }, * if it does not have them already * * @param beanReference * @return */ public String getExpression(String beanReference){ String exp = beanReference; if (!isValueBinding(beanReference)) { exp = EXPRESSION_BEGIN+beanReference+EXPRESSION_END; } return exp; } @SuppressWarnings("unchecked") protected <T>T getExpressionValue(FacesContext ctx, String expression) { ValueExpression vexp = getValueExpression(expression); return vexp != null ? (T)vexp.getValue(ctx.getELContext()) : null; } /** * <p> * This method finds a bean instance from a given beanId.<br/> * * </p> * @param beanId - could be either expression like #{bean.method} or just beanId like beanId * @return */ public <T>T getBeanInstance(String beanId) { FacesContext context = FacesContext.getCurrentInstance(); String expr; if (isValueBinding(beanId)) expr = beanId; else expr = getExpression(beanId); ELContext elContext = context.getELContext(); ValueExpression ve = context.getApplication().getExpressionFactory().createValueExpression(elContext, expr, Object.class); @SuppressWarnings("unchecked") T bean = (T) ve.getValue(elContext); return bean; } public IWBundle getBundle(FacesContext ctx, String bundleIdentifier) { IWMainApplication iwma = IWMainApplication.getIWMainApplication(ctx); return iwma.getBundle(bundleIdentifier); } public IWBundle getBundle(IWUserContext iwuc, String bundleIdentifier) { IWMainApplication iwma = iwuc.getApplicationContext().getIWMainApplication(); return iwma.getBundle(bundleIdentifier); } @Autowired private WebUtil webUtil = null; protected WebUtil getWebUtil() { if (this.webUtil == null) { ELUtil.getInstance().autowire(this); } return this.webUtil; } }