/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you under the Apache License, Version 2.0 (the | |
* "License"); you may not use this file except in compliance | |
* with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, | |
* software distributed under the License is distributed on an | |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
* KIND, either express or implied. See the License for the | |
* specific language governing permissions and limitations | |
* under the License. | |
*/ | |
package org.apache.empire.jsf2.app; | |
import java.io.File; | |
import java.io.IOException; | |
import java.sql.Connection; | |
import java.util.HashMap; | |
import java.util.Iterator; | |
import java.util.Map; | |
import javax.el.ValueExpression; | |
import javax.faces.application.FacesMessage; | |
import javax.faces.component.UIComponent; | |
import javax.faces.component.UIInput; | |
import javax.faces.component.UIViewRoot; | |
import javax.faces.context.ExternalContext; | |
import javax.faces.context.FacesContext; | |
import javax.servlet.ServletContext; | |
import javax.servlet.http.HttpServletRequest; | |
import org.apache.empire.commons.ObjectUtils; | |
import org.apache.empire.commons.StringUtils; | |
import org.apache.empire.data.Column; | |
import org.apache.empire.db.DBDatabase; | |
import org.apache.empire.exceptions.EmpireException; | |
import org.apache.empire.exceptions.InternalException; | |
import org.apache.empire.exceptions.ItemNotFoundException; | |
import org.apache.empire.jsf2.impl.FacesImplementation; | |
import org.apache.empire.jsf2.pages.Page; | |
import org.apache.empire.jsf2.pages.PageDefinition; | |
import org.apache.empire.jsf2.pages.PageOutcome; | |
import org.apache.empire.jsf2.utils.ParameterMap; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
public class FacesUtils | |
{ | |
private static final Logger log = LoggerFactory.getLogger(FacesUtils.class); | |
public static final String SKIP_INPUT_VALIDATION_PARAM = "empire.jsf.input.skipValidation"; | |
/* App */ | |
public static WebApplication getWebApplication() | |
{ | |
return WebApplication.getInstance(); | |
} | |
public static FacesImplementation getFacesImplementation() | |
{ | |
return getWebApplication().getFacesImplementation(); | |
} | |
public static FacesContext getContext() | |
{ | |
return FacesContext.getCurrentInstance(); | |
} | |
/* Session */ | |
public static Map<String, Object> getSessionMap(final FacesContext fc) | |
{ | |
return fc.getExternalContext().getSessionMap(); | |
} | |
/* Request */ | |
public static HttpServletRequest getHttpRequest(final FacesContext fc) | |
{ | |
return (HttpServletRequest) fc.getExternalContext().getRequest(); | |
} | |
public static String getRequestUserAgent() | |
{ | |
String agent = null; | |
Object req = FacesContext.getCurrentInstance().getExternalContext().getRequest(); | |
if (req instanceof HttpServletRequest) | |
{ | |
agent = ((HttpServletRequest)req).getHeader("user-agent"); | |
} | |
return (agent!=null ? agent : ""); | |
} | |
public static boolean isRequestUserAgentIE() | |
{ | |
String userAgent = getRequestUserAgent(); | |
return (userAgent.indexOf("MSIE")>=0); | |
} | |
public static String getRequestContextPath() | |
{ | |
return FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath(); | |
} | |
public static Object getRequestAttribute(final String key) | |
{ | |
FacesContext fc = getContext(); | |
return getRequestAttribute(fc, key); | |
} | |
public static Object getRequestAttribute(final FacesContext fc, final String key) | |
{ | |
return getHttpRequest(fc).getAttribute(key); | |
} | |
public static void setRequestAttribute(final String key, Object value) | |
{ | |
FacesContext fc = getContext(); | |
setRequestAttribute(fc, key, value); | |
} | |
public static void setRequestAttribute(final FacesContext fc, final String key, Object value) | |
{ | |
if (value!=null) | |
getHttpRequest(fc).setAttribute(key, value); | |
else | |
getHttpRequest(fc).removeAttribute(key); | |
} | |
public static String getRequestParam(final FacesContext context, final String param) | |
{ | |
return context.getExternalContext().getRequestParameterMap().get(param); | |
} | |
public static String getRequestParam(final String key) | |
{ | |
FacesContext fc = getContext(); | |
return getRequestParam(fc, key); | |
} | |
public static boolean isSkipInputValidation(final FacesContext fc) | |
{ | |
// Skip validate | |
String val = FacesUtils.getRequestParam(fc, SKIP_INPUT_VALIDATION_PARAM); | |
return (val!=null && ObjectUtils.getBoolean(val)); | |
} | |
public static boolean isSkipInputValidation() | |
{ | |
FacesContext fc = getContext(); | |
return isSkipInputValidation(fc); | |
} | |
/* Navigation */ | |
public static void redirectDirectly(final FacesContext fc, final String url) | |
{ | |
try | |
{ // log | |
if (log.isDebugEnabled()) | |
log.debug("Redirecting directly to {}.", url); | |
if (fc.getResponseComplete()) | |
log.warn("Redirecting although response is already complete!"); | |
// redirectDirectly | |
fc.getExternalContext().redirect(url); | |
fc.responseComplete(); | |
} | |
catch (IOException e) | |
{ | |
log.error("Unable to redirect to " + url); | |
} | |
} | |
public static void redirectDirectly(final FacesContext fc, final PageOutcome outcome) | |
{ | |
String ctxPath = fc.getExternalContext().getRequestContextPath(); | |
String pageURI = ctxPath + outcome.toString(); | |
FacesUtils.redirectDirectly(fc, pageURI); | |
} | |
public static void redirectDirectly(final FacesContext fc, final PageDefinition page) | |
{ | |
FacesUtils.redirectDirectly(fc, page.getOutcome()); | |
} | |
/* Connection */ | |
public Connection getConnection(final FacesContext fc, DBDatabase db) | |
{ | |
return getWebApplication().getConnectionForRequest(fc, db); | |
} | |
public void releaseAllConnections(final FacesContext fc, boolean commit) | |
{ | |
getWebApplication().releaseAllConnections(fc, commit); | |
} | |
public void releaseAllConnections(final FacesContext fc, DBDatabase db, boolean commit) | |
{ | |
getWebApplication().releaseConnection(fc, db, commit); | |
} | |
/* Pages */ | |
public static Page getPage(final FacesContext fc) | |
{ | |
UIViewRoot vr = fc.getViewRoot(); | |
if (vr==null) | |
throw new ItemNotFoundException("ViewRoot"); | |
// find page | |
Page page = (Page)vr.getViewMap().get("page"); | |
if (page==null) | |
throw new ItemNotFoundException("page"); | |
// ok | |
return page; | |
} | |
/* Parameter-map */ | |
public static final String PARAMETER_MAP_ATTRIBUTE = "PARAMETER_MAP"; | |
public static final String PARAMETER_MAP_CLASS_ATTRIBUTE = "PARAMETER_MAP_CLASS"; | |
public static void setParameterMapClass(final FacesContext fc, Class<? extends ParameterMap>clazz) | |
{ | |
Map<String, Object> am = fc.getExternalContext().getApplicationMap(); | |
am.put(PARAMETER_MAP_CLASS_ATTRIBUTE, clazz); | |
} | |
public static ParameterMap getParameterMap(final FacesContext fc) | |
{ | |
Map<String, Object> sm = fc.getExternalContext().getSessionMap(); | |
ParameterMap pm = (ParameterMap)sm.get(PARAMETER_MAP_ATTRIBUTE); | |
if (pm==null) | |
{ try | |
{ // Create Paramter Map | |
Map<String, Object> am = fc.getExternalContext().getApplicationMap(); | |
Object pmClass = am.get(PARAMETER_MAP_CLASS_ATTRIBUTE); | |
if (pmClass instanceof Class<?>) { | |
// ParamterMapClass provided as Object | |
pm = (ParameterMap)((Class<?>)pmClass).newInstance(); | |
} | |
else if (pmClass instanceof String) { | |
// ParamterMapClass provided as String | |
pm = (ParameterMap)Class.forName((String)pmClass).newInstance(); | |
} | |
else { | |
// not provided, use default | |
pm = new ParameterMap(); | |
} | |
} | |
catch (ClassNotFoundException e) | |
{ | |
throw new InternalException(e); | |
} | |
catch (InstantiationException e) | |
{ | |
throw new InternalException(e); | |
} | |
catch (IllegalAccessException e) | |
{ | |
throw new InternalException(e); | |
} | |
// put on session | |
sm.put(PARAMETER_MAP_ATTRIBUTE, pm); | |
} | |
return pm; | |
} | |
public static ParameterMap getParameterMap() | |
{ | |
return getParameterMap(getContext()); | |
} | |
/* PageResource-map */ | |
public static final String PAGE_RESOURCE_MAP_ATTRIBUTE = "pageResources"; /** use el-expression: #{pageResources.xxx} **/ | |
@SuppressWarnings("unchecked") | |
public static Map<String, Object> getPageResourceMap(final FacesContext fc) | |
{ | |
Map<String, Object> sm = fc.getExternalContext().getSessionMap(); | |
Map<String, Object> rm = (Map<String, Object>)sm.get(PAGE_RESOURCE_MAP_ATTRIBUTE); | |
if (rm==null) | |
{ rm = new HashMap<String, Object>(); | |
sm.put(PAGE_RESOURCE_MAP_ATTRIBUTE, rm); | |
} | |
return rm; | |
} | |
public static Map<String, Object> getPageResourceMap() | |
{ | |
return getPageResourceMap(getContext()); | |
} | |
/* Managed Beans */ | |
public static Object getManagedBean(final FacesContext fc, final String name) | |
{ | |
if (fc == null) | |
{ | |
throw new NullPointerException("context must not be null"); | |
} | |
if (name == null) | |
{ | |
throw new NullPointerException("name must not be null"); | |
} | |
/* | |
final ELContext elcontext = fc.getELContext(); | |
final Application application = fc.getApplication(); | |
return application.getELResolver().getValue(elcontext, null, name); | |
*/ | |
return getWebApplication().getFacesImplementation().getManagedBean(name, fc); | |
} | |
public static <T> T getManagedBean(final FacesContext fc, final Class<T> cls, final String name) | |
{ | |
@SuppressWarnings("unchecked") | |
T bean = (T)getManagedBean(fc, name); | |
if (bean==null) | |
{ log.warn("Managed Bean {} ist not available.", name); | |
throw new ItemNotFoundException(name); | |
} | |
return bean; | |
} | |
public static <T> T getManagedBean(final FacesContext fc, final Class<T> cls) | |
{ | |
String name = cls.getName(); | |
int i = name.lastIndexOf('.')+1; | |
name = name.substring(i, i+1).toLowerCase()+name.substring(i+1); | |
return getManagedBean(fc, cls, name); | |
} | |
public static <T> T getManagedBean(final Class<T> cls) | |
{ | |
FacesContext fc = getContext(); | |
return getManagedBean(fc, cls); | |
} | |
/* | |
@SuppressWarnings("unchecked") | |
public static <T> T findBean(String beanName) { | |
FacesContext context = FacesContext.getCurrentInstance(); | |
return (T) context.getApplication().evaluateExpressionGet(context, "#{" + beanName + "}", Object.class); | |
} | |
*/ | |
/* file */ | |
public static String getRealPath(final FacesContext fc, String path) | |
{ | |
return (((ServletContext)fc.getExternalContext().getContext())).getRealPath(path); | |
} | |
public static String getFilePath(final FacesContext fc, String path, String file) | |
{ | |
String realPath = getRealPath(fc, path); | |
return realPath.endsWith(File.separator) ? realPath+file : realPath + File.separator + file ; | |
} | |
/* Messages */ | |
public static TextResolver getTextResolver(final FacesContext fc) | |
{ | |
return getWebApplication().getTextResolver(fc); | |
} | |
public static String getMessage(final FacesContext fc, String key) | |
{ | |
return getTextResolver(fc).resolveKey(key); | |
} | |
public static String getMessage(String messageKey) | |
{ | |
return getMessage(getContext(), messageKey); | |
} | |
public static void addInfoMessage(FacesContext fc, String clientId, String msg) | |
{ | |
fc.addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg)); | |
} | |
public static void addInfoMessage(FacesContext fc, String msg) | |
{ | |
addInfoMessage(fc, null, msg); | |
} | |
public static void addErrorMessage(FacesContext fc, String clientId, String msg) | |
{ | |
fc.addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg)); | |
} | |
public static void addErrorMessage(FacesContext fc, String msg) | |
{ | |
addErrorMessage(fc, null, msg); | |
} | |
/** | |
* indicates whether submitted values in InputControl should be cleared or preserved. | |
* Default is true. | |
* @param fc the faces context | |
* @return true if the submitted values should be cleared or false if they shold be preserved | |
public static boolean isClearSubmittedValues(FacesContext fc) | |
{ | |
Object validate = fc.getExternalContext().getRequestMap().get("CLEAR_SUBMITTED_VALUES"); | |
return (validate!=null ? ObjectUtils.getBoolean(validate) : false); | |
} | |
public static void setClearSubmittedValues(FacesContext fc, boolean validate) | |
{ | |
fc.getExternalContext().getRequestMap().put("CLEAR_SUBMITTED_VALUES", validate); | |
} | |
*/ | |
public static FacesMessage getFacesErrorMessage(FacesContext fc, Throwable t) | |
{ | |
if (!(t instanceof EmpireException)) | |
t = new InternalException(t); | |
// Get Message | |
TextResolver tr = getWebApplication().getTextResolver(fc); | |
String msg = tr.getExceptionMessage((EmpireException)t); | |
// create Faces Message | |
return new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, null); | |
} | |
public static void redirectFromError(Page page, Throwable t) | |
{ | |
PageOutcome pageTarget = page.getPageDefinition().getOutcome(); | |
// throw new InternalException(e); | |
FacesContext fc = FacesUtils.getContext(); | |
boolean committed = fc.getExternalContext().isResponseCommitted(); | |
if (committed) | |
{ log.warn("Cannot redirect to {} from an already committed response! Error is {}.", pageTarget, t.getMessage()); | |
return; | |
} | |
// redirect to target page | |
FacesMessage facesMsg = getFacesErrorMessage(fc, t); | |
ExternalContext ec = fc.getExternalContext(); | |
ec.getSessionMap().put("PAGE_SESSION_MESSAGE", facesMsg); | |
// redirect | |
FacesUtils.redirectDirectly(fc, pageTarget); | |
} | |
/* Component search */ | |
public static UIInput findInputComponent(UIComponent parent, Column column) | |
{ | |
// Get Children | |
Iterator<UIComponent> children = parent.getFacetsAndChildren(); | |
while (children.hasNext()) | |
{ // Iterate through all children | |
UIComponent nextChild = children.next(); | |
log.info("Checking child {}", nextChild.getClass().getName()); | |
if (nextChild instanceof UIInput) | |
{ // Check Column Attribute | |
Object col = nextChild.getAttributes().get("column"); | |
if (col==null) | |
{ // Check ID | |
ValueExpression ve = nextChild.getValueExpression("column"); | |
if (ve!=null) | |
log.warn("TODO: evaluate Value Expression!"); | |
} | |
else if (column.equals(col)) | |
{ // check form | |
return (UIInput)nextChild; | |
} | |
} | |
else | |
{ // recurse children and facets | |
UIInput input = findInputComponent(nextChild, column); | |
if (input!=null) | |
return input; | |
} | |
} | |
// Not found | |
return null; | |
} | |
public static UIInput findInputComponent(FacesContext fc, String formId, Column column) | |
{ | |
UIComponent parent = fc.getViewRoot(); | |
if (StringUtils.isNotEmpty(formId)) | |
{ | |
parent = WebApplication.findChildComponent(parent, formId); | |
if (parent==null) | |
return null; // not found | |
} | |
// find | |
return findInputComponent(parent, column); | |
} | |
} |