package com.idega.facelets.ui;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.component.UIComponent;
import javax.faces.component.UIParameter;
import javax.faces.context.FacesContext;
import com.idega.presentation.IWBaseComponent;
import com.idega.servlet.filter.IWBundleResourceFilter;
import com.idega.util.CoreConstants;
import com.idega.util.expression.ELUtil;
import com.sun.facelets.Facelet;
import com.sun.facelets.FaceletFactory;
/**
*
* @author <a href="civilis@idega.com">Vytautas Čivilis</a>
* @version $Revision: 1.4 $
*
* Last modified: $Date: 2008/02/14 21:29:08 $ by $Author: civilis $
*
*/
public class FaceletComponent extends IWBaseComponent {
private String faceletURI;
private static final String faceletFactoryFactoryBeanId = "faceletFactoryFactory";
public static final String COMPONENT_TYPE = "FaceletComponent";
public FaceletComponent() { }
public FaceletComponent(String faceletURI) {
setFaceletURI(faceletURI);
}
@Override
protected void initializeComponent(FacesContext context) {
super.initializeComponent(context);
String resourceURI = getFaceletURI();
if(resourceURI == null || CoreConstants.EMPTY.equals(resourceURI))
return;
IWBundleResourceFilter.checkCopyOfResourceToWebapp(context, resourceURI);
}
@Override
public void encodeBegin(FacesContext context) throws IOException {
super.encodeBegin(context);
try {
String resourceURI = getFaceletURI();
if(resourceURI == null || CoreConstants.EMPTY.equals(resourceURI))
return;
List<UIParameter> paramList = new ArrayList<UIParameter>();
for(UIComponent c : getChildren()){
if(c instanceof UIParameter){
paramList.add((UIParameter) c);
}
}
FaceletFactory faceletFactory = ((FaceletFactoryFactory)getBeanInstance(faceletFactoryFactoryBeanId)).createFaceletFactory(paramList);
Facelet facelet;
synchronized (faceletFactory) {
// TODO: perhaps facelet factory is thread safe?
facelet = faceletFactory.getFacelet(resourceURI);
}
facelet.apply(context, this);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public Object saveState(FacesContext ctx) {
Object values[] = new Object[2];
values[0] = super.saveState(ctx);
values[1] = faceletURI;
return values;
}
@Override
public void restoreState(FacesContext ctx, Object state) {
Object values[] = (Object[]) state;
super.restoreState(ctx, values[0]);
faceletURI = (String) values[1];
}
public String getFaceletURI() {
if (faceletURI == null) {
ValueExpression vb = getValueExpression("faceletURI");
if (vb != null) {
return (String) vb.getValue(getFacesContext().getELContext());
}
return null;
} else if(ELUtil.isExpression(faceletURI)){
FacesContext fContext = FacesContext.getCurrentInstance();
ValueExpression valExpr = ELUtil.createValueExpression(fContext, faceletURI, String.class);
return (String) valExpr.getValue(fContext.getELContext());
} else {
return faceletURI;
}
}
public void setFaceletURI(String faceletURI) {
if(this.faceletURI != null)
throw new UnsupportedOperationException("Facelet URI already set. Create new component. URI: "+this.faceletURI);
this.faceletURI = faceletURI;
}
}