This is an automated email from the ASF dual-hosted git repository.
doebele pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/empire-db.git
The following commit(s) were added to refs/heads/master by this push:
new 5f658fb7 EMPIREDB-451 Improved FacesUtils and FacesMessage handling
5f658fb7 is described below
commit 5f658fb75f66ae5ecd2b08c75a2312f810dee76d
Author: Rainer Döbele <[email protected]>
AuthorDate: Wed Dec 11 10:43:49 2024 +0100
EMPIREDB-451
Improved FacesUtils and FacesMessage handling
---
.../org/apache/empire/jakarta/app/FacesUtils.java | 160 ++++++++++++++-------
.../apache/empire/jakarta/app/WebApplication.java | 66 +++++++++
.../empire/jakarta/controls/InputControl.java | 27 ++--
.../empire/jakarta/controls/TextInputControl.java | 4 +-
.../java/org/apache/empire/jakarta/pages/Page.java | 67 ++++-----
.../org/apache/empire/jsf2/app/FacesUtils.java | 132 +++++++++++------
.../org/apache/empire/jsf2/app/WebApplication.java | 66 +++++++++
.../apache/empire/jsf2/controls/InputControl.java | 9 +-
.../empire/jsf2/controls/TextInputControl.java | 4 +-
.../java/org/apache/empire/jsf2/pages/Page.java | 53 +++----
10 files changed, 395 insertions(+), 193 deletions(-)
diff --git
a/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/app/FacesUtils.java
b/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/app/FacesUtils.java
index edbd5601..24206695 100644
---
a/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/app/FacesUtils.java
+++
b/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/app/FacesUtils.java
@@ -23,33 +23,37 @@ import java.io.IOException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.Locale;
import java.util.Map;
-import jakarta.el.ValueExpression;
-import jakarta.faces.application.FacesMessage;
-import jakarta.faces.component.UIComponent;
-import jakarta.faces.component.UIInput;
-import jakarta.faces.component.UIViewRoot;
-import jakarta.faces.context.ExternalContext;
-import jakarta.faces.context.FacesContext;
-import jakarta.faces.event.ActionEvent;
-import jakarta.servlet.ServletContext;
-import jakarta.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.exceptions.EmpireException;
import org.apache.empire.exceptions.InternalException;
+import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.ItemNotFoundException;
import org.apache.empire.jakarta.impl.FacesImplementation;
import org.apache.empire.jakarta.pages.Page;
import org.apache.empire.jakarta.pages.PageDefinition;
import org.apache.empire.jakarta.pages.PageOutcome;
+import org.apache.empire.jakarta.utils.HtmlUtils;
import org.apache.empire.jakarta.utils.ParameterMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import jakarta.el.ValueExpression;
+import jakarta.faces.application.FacesMessage;
+import jakarta.faces.application.FacesMessage.Severity;
+import jakarta.faces.application.ProjectStage;
+import jakarta.faces.component.UIComponent;
+import jakarta.faces.component.UIInput;
+import jakarta.faces.component.UIViewRoot;
+import jakarta.faces.context.ExternalContext;
+import jakarta.faces.context.FacesContext;
+import jakarta.faces.event.ActionEvent;
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.http.HttpServletRequest;
+
public class FacesUtils
{
@@ -57,6 +61,12 @@ public class FacesUtils
public static final String SKIP_INPUT_VALIDATION_PARAM =
"empire.jsf.input.skipValidation";
+ /* Develpment stage */
+ public static boolean isDevelopmentStage(final FacesContext fc)
+ {
+ return fc.getApplication().getProjectStage()==ProjectStage.Development;
+ }
+
/* App */
public static WebApplication getWebApplication()
@@ -73,6 +83,11 @@ public class FacesUtils
{
return FacesContext.getCurrentInstance();
}
+
+ public static Locale getContextLocale(final FacesContext fc)
+ {
+ return getWebApplication().getContextLocale(fc);
+ }
/* Session */
@@ -398,54 +413,50 @@ public class FacesUtils
return getWebApplication().getTextResolver(fc);
}
- public static String getMessage(final FacesContext fc, String key)
+ public static String resolveText(final FacesContext fc, String text)
{
- return getTextResolver(fc).resolveKey(key);
+ return getTextResolver(fc).resolveText(text);
}
- public static String getMessage(String messageKey)
+ public static String resolveText(String text)
{
- return getMessage(getContext(), messageKey);
+ return getTextResolver(getContext()).resolveText(text);
}
-
- public static String formatMessage(String msgKey, Object... params)
- {
- TextResolver tr = getTextResolver(FacesContext.getCurrentInstance());
- String pattern = tr.resolveKey(msgKey);
- return MessageFormat.format(pattern, params);
- }
-
- /*
- public static void addInfoMessage(FacesContext fc, String clientId, String
msg)
+
+ public static String getMessage(final FacesContext fc, String key)
{
- fc.addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_INFO,
msg, msg));
+ if (StringUtils.isEmpty(key))
+ throw new InvalidArgumentException("key", key);
+ TextResolver tr = getTextResolver(fc);
+ return (key.startsWith(TextResolver.MSG_KEY_INDICATOR) ?
tr.resolveText(key) : tr.resolveKey(key));
}
- public static void addInfoMessage(FacesContext fc, String msg)
+ public static String getMessage(String messageKey)
{
- addInfoMessage(fc, null, msg);
+ return getMessage(getContext(), messageKey);
}
- public static void addWarnMessage(FacesContext fc, String clientId, String
msg)
+ public static String formatMessage(final FacesContext fc, String msgKey,
Object... params)
{
- fc.addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_WARN,
msg, msg));
- }
-
- public static void addWarnMessage(FacesContext fc, String msg)
- {
- addWarnMessage(fc, null, msg);
+ String pattern = getMessage(fc, msgKey);
+ return MessageFormat.format(pattern, params);
}
- public static void addErrorMessage(FacesContext fc, String clientId,
String msg)
+ public static String formatMessage(String msgKey, Object... params)
{
- fc.addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_ERROR,
msg, msg));
+ return formatMessage(getContext(), msgKey, params);
}
- public static void addErrorMessage(FacesContext fc, String msg)
+ /**
+ * Escapes Text for Html
+ * Uses HtmlUtils.getInstance() for escaping
+ * @param text the text to escape
+ * @return the escaped text
+ */
+ public static String escapeHtml(String text)
{
- addErrorMessage(fc, null, msg);
+ return HtmlUtils.getInstance().escapeText(text);
}
- */
/*
* indicates whether submitted values in InputControl should be cleared or
preserved.
@@ -463,36 +474,77 @@ public class FacesUtils
fc.getExternalContext().getRequestMap().put("CLEAR_SUBMITTED_VALUES",
validate);
}
*/
+
+ public static void addFacesMessage(FacesContext fc, UIComponent comp,
FacesMessage facesMsg)
+ {
+ if (facesMsg==null)
+ return;
+ String clientId = (comp!=null ? comp.getClientId() : null);
+ fc.addMessage(clientId, facesMsg);
+ }
+
+ public static void addFacesMessage(UIComponent comp, Severity severity,
String message, Object... params)
+ {
+ FacesContext fc = getContext();
+ addFacesMessage(fc, comp, getWebApplication().getFacesMessage(fc,
severity, message, params));
+ }
+
+ public static void addInfoMessage(String msg, Object... params)
+ {
+ addFacesMessage(null, FacesMessage.SEVERITY_INFO, msg, params);
+ }
+
+ public static void addWarnMessage(String msg, Object... params)
+ {
+ addFacesMessage(null, FacesMessage.SEVERITY_WARN, msg, params);
+ }
+
+ public static void addErrorMessage(String msg, Object... params)
+ {
+ addFacesMessage(null, FacesMessage.SEVERITY_ERROR, msg, params);
+ }
+
+ public static void addErrorMessage(UIComponent comp, Throwable t)
+ {
+ FacesContext fc = getContext();
+ addFacesMessage(fc, comp, getFacesErrorMessage(fc, t));
+ }
+
+ public static void addErrorMessage(Throwable t)
+ {
+ addErrorMessage(null, t);
+ }
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);
+ return getWebApplication().getFacesErrorMessage(fc, null, t);
}
- public static void redirectFromError(Page page, Throwable t)
+ public static void redirectFromError(Page page, FacesMessage errorMsg)
{
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());
+ { log.warn("Cannot redirect to {} from an already committed
response! Error is {}.", pageTarget, errorMsg.getSummary());
return;
}
// redirect to target page
- FacesMessage facesMsg = getFacesErrorMessage(fc, t);
- ExternalContext ec = fc.getExternalContext();
- ec.getSessionMap().put(Page.SESSION_MESSAGE, facesMsg);
+ if (errorMsg!=null) {
+ ExternalContext ec = fc.getExternalContext();
+ ec.getSessionMap().put(Page.SESSION_MESSAGE, errorMsg);
+ }
// redirect
FacesUtils.redirectDirectly(fc, pageTarget);
}
-
+
+ public static void redirectFromError(Page page, Throwable t)
+ {
+ FacesContext fc = FacesUtils.getContext();
+ FacesMessage facesMsg = getFacesErrorMessage(fc, t);
+ redirectFromError(page, facesMsg);
+ }
/* Component search */
public static UIInput findInputComponent(UIComponent parent, Column column)
diff --git
a/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/app/WebApplication.java
b/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/app/WebApplication.java
index c40ecf84..ac6b8293 100644
---
a/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/app/WebApplication.java
+++
b/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/app/WebApplication.java
@@ -20,6 +20,7 @@ package org.apache.empire.jakarta.app;
import java.sql.Connection;
import java.sql.SQLException;
+import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
@@ -33,6 +34,7 @@ import org.apache.empire.data.DataType;
import org.apache.empire.db.DBDatabase;
import org.apache.empire.db.context.DBRollbackManager;
import org.apache.empire.db.context.DBRollbackManager.ReleaseAction;
+import org.apache.empire.exceptions.EmpireException;
import org.apache.empire.exceptions.InternalException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.NotSupportedException;
@@ -252,6 +254,70 @@ public abstract class WebApplication
return getTextResolver(getContextLocale(ctx));
}
+ /**
+ * Returns a FacesMessage
+ * @param ctx the FacesContext
+ * @param severity the message severity
+ * @param msg the message or message key
+ * @param params the message params
+ * @return the FacesMessage or null to ignore
+ */
+ public FacesMessage getFacesMessage(FacesContext ctx, Severity severity,
String msg, Object... params)
+ {
+ TextResolver resolver = getTextResolver(getContextLocale(ctx));
+ msg = resolver.resolveText(msg);
+ if (params.length>0)
+ { // translate params
+ for (int i=0; i<params.length; i++)
+ if (params[i] instanceof String)
+ params[i] = resolver.resolveText((String)params[i]);
+ else if ((params[i] instanceof Integer) || (params[i]
instanceof Long))
+ params[i] = String.valueOf(params[i]); // avoid group
separator
+ // format
+ msg = MessageFormat.format(msg, params);
+ }
+ return new FacesMessage(severity, msg, null);
+ }
+
+ /**
+ * Returns a FacesMessage for an Exception
+ * @param ctx the FacesContext
+ * @param errorContext the error context (optional)
+ * @param t the exception
+ * @return the FacesMessage or null to ignore
+ */
+ public FacesMessage getFacesErrorMessage(FacesContext ctx, String
errorContext, Throwable t)
+ {
+ // Wrap exception if necessary
+ EmpireException e = (t instanceof EmpireException) ?
((EmpireException)t) : new InternalException(t);
+ // Get Message
+ TextResolver tr = getTextResolver(ctx);
+ String msg = tr.getExceptionMessage(e);
+ String msgDetail = extractErrorMessageDetail(errorContext, t, 3);
+ // create Faces Message
+ return new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msgDetail);
+ }
+
+ protected String extractErrorMessageDetail(String errorContext, Throwable
e, int stackTraceElements)
+ {
+ StringBuilder b = new StringBuilder();
+ if (errorContext!=null)
+ { // Append context String
+ b.append(errorContext);
+ b.append(": ");
+ }
+ b.append(e.toString());
+ b.append("\r\nat:");
+ StackTraceElement[] stack = e.getStackTrace();
+ int len = (stack.length>stackTraceElements) ? stackTraceElements :
stack.length;
+ for (int i=0; i<len; i++)
+ {
+ b.append(stack[i].toString());
+ b.append("\r\n");
+ }
+ return b.toString();
+ }
+
/**
* checks if the current context contains an error
* @param fc the FacesContext
diff --git
a/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/controls/InputControl.java
b/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/controls/InputControl.java
index e5eaed45..b1641425 100644
---
a/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/controls/InputControl.java
+++
b/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/controls/InputControl.java
@@ -432,7 +432,7 @@ public abstract class InputControl
{ // Null
styleClass += " eValNull";
}
- else if (dataType.isNumeric())
+ else if (dataType.isNumeric() && value instanceof Number)
{ // Check negative
if (ObjectUtils.getLong(value)<0)
styleClass += " eValNeg";
@@ -524,13 +524,19 @@ public abstract class InputControl
{
// UIInput
if (comp instanceof UIInput)
- {
+ { // Check LocalValue set
UIInput input = (UIInput)comp;
- if (input.isLocalValueSet())
- { input.setValue(null);
- input.setLocalValueSet(false);
- // log.debug("clearLocalValues performed for {}",
input.getClass().getName());
+ if (input.isValid() && input.isLocalValueSet())
+ { // Check ValueExpression
+ // @see: UIInput:updateModel(FacesContext context)
+ ValueExpression expression = input.getValueExpression("value");
+ if (expression != null)
+ { // Reset localValue if ValueExpression is set
+ input.resetValue();
+ }
}
+ // we're done here
+ return;
}
// clearLocalValues of all facets and children of this UIComponent
if (comp.getFacetCount() > 0)
@@ -785,7 +791,7 @@ public abstract class InputControl
if (hasFormatOption(vi, "noencode"))
return s;
// Encode Html
- return escapeHTML(s);
+ return escapeHtml(s);
}
/**
@@ -825,12 +831,11 @@ public abstract class InputControl
*/
/**
- * escapes a String for html
- *
- * @param text
+ * Escapes a String for html
+ * @param text the text to escape
* @return the escaped html String
*/
- protected String escapeHTML(String text)
+ protected String escapeHtml(String text)
{
return HtmlUtils.getInstance().escapeText(text);
}
diff --git
a/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/controls/TextInputControl.java
b/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/controls/TextInputControl.java
index d7896487..24889175 100644
---
a/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/controls/TextInputControl.java
+++
b/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/controls/TextInputControl.java
@@ -287,7 +287,7 @@ public class TextInputControl extends InputControl
return s;
// Encoded text
if (escapeHTML)
- s = escapeHTML(s);
+ s = escapeHtml(s);
return s;
}
if (dataType == DataType.INTEGER || dataType == DataType.AUTOINC)
@@ -316,7 +316,7 @@ public class TextInputControl extends InputControl
// Convert to String
if (escapeHTML)
{
- return escapeHTML(String.valueOf(value));
+ return escapeHtml(String.valueOf(value));
}
return String.valueOf(value);
}
diff --git
a/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/pages/Page.java
b/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/pages/Page.java
index 4810d53f..9ce53cf4 100644
---
a/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/pages/Page.java
+++
b/empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/pages/Page.java
@@ -19,32 +19,29 @@
package org.apache.empire.jakarta.pages;
import java.lang.reflect.Method;
-import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import jakarta.faces.application.FacesMessage;
-import jakarta.faces.application.FacesMessage.Severity;
-import jakarta.faces.application.NavigationHandler;
-import jakarta.faces.context.ExternalContext;
-import jakarta.faces.context.FacesContext;
-
import org.apache.empire.commons.StringUtils;
import org.apache.empire.db.DBRowSet;
-import org.apache.empire.exceptions.EmpireException;
-import org.apache.empire.exceptions.InternalException;
+import org.apache.empire.exceptions.InvalidOperationException;
import org.apache.empire.exceptions.ItemNotFoundException;
import org.apache.empire.jakarta.app.FacesUtils;
import org.apache.empire.jakarta.app.TextResolver;
import org.apache.empire.jakarta.app.WebApplication;
import org.apache.empire.jakarta.utils.ParameterMap;
import org.apache.empire.jakarta.utils.ParameterObject;
-import org.apache.empire.exceptions.InvalidOperationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import jakarta.faces.application.FacesMessage;
+import jakarta.faces.application.FacesMessage.Severity;
+import jakarta.faces.application.NavigationHandler;
+import jakarta.faces.context.ExternalContext;
+import jakarta.faces.context.FacesContext;
+
public abstract class Page // *Deprecated* implements Serializable
{
// *Deprecated* private static final long serialVersionUID = 1L;
@@ -289,25 +286,22 @@ public abstract class Page // *Deprecated* implements
Serializable
ec.getSessionMap().put(SESSION_MESSAGE, facesMsg);
}
- protected void setSessionError(Throwable e)
+ protected void setSessionError(Throwable t)
{
// Set Session Message
- String msg = extractErrorMessage(e);
- String detail = extractErrorMessageDetail(action, e, 1);
- if (log.isDebugEnabled())
- log.debug(msg + "\r\n" + detail, e);
- FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR,
msg, detail);
+ FacesContext fc = FacesContext.getCurrentInstance();
+ FacesMessage facesMsg = FacesUtils.getFacesErrorMessage(fc, t);
setSessionMessage(facesMsg);
}
- protected boolean handleActionError(String action, Throwable e)
+ protected boolean handleActionError(String action, Throwable t)
{
- // Set Faces Message
- String msg = extractErrorMessage(e);
- String detail = extractErrorMessageDetail(action, e, 1);
- // log.error(msg + "\r\n" + detail);
- FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR,
msg, detail);
- setSessionMessage(facesMsg);
+ // the error context
+ String errorContext = StringUtils.concat(getPageName(), ":", action);
+ // get Message
+ WebApplication app = FacesUtils.getWebApplication();
+ FacesContext fc = FacesContext.getCurrentInstance();
+ FacesMessage facesMsg = app.getFacesErrorMessage(fc, errorContext, t);
// Return to parent page
PageDefinition parentPage = getParentPage();
if (parentPage == null)
@@ -315,24 +309,14 @@ public abstract class Page // *Deprecated* implements
Serializable
return false;
}
// redirect
+ setSessionMessage(facesMsg);
navigateTo(parentPage.getRedirect());
return true;
}
protected void addFacesMessage(Severity severity, String msg, Object...
params)
{
- TextResolver resolver = getTextResolver();
- msg = resolver.resolveText(msg);
- if (params.length>0)
- { // translate params
- for (int i=0; i<params.length; i++)
- if (params[i] instanceof String)
- params[i] = resolver.resolveText((String)params[i]);
- // format
- msg = MessageFormat.format(msg, params);
- }
- FacesMessage facesMsg = new FacesMessage(severity, msg, msg);
- FacesContext.getCurrentInstance().addMessage(getPageName(), facesMsg);
+ FacesUtils.addFacesMessage(null, severity, msg, params);
}
public final void addInfoMessage(String msg, Object... params)
@@ -350,16 +334,14 @@ public abstract class Page // *Deprecated* implements
Serializable
addFacesMessage(FacesMessage.SEVERITY_ERROR, msg, params);
}
- public void setErrorMessage(Throwable e)
+ public void setErrorMessage(Throwable t)
{
- String msg = extractErrorMessage(e);
- String detail = extractErrorMessageDetail(action, e, 1);
- if (log.isDebugEnabled())
- log.debug(msg + "\r\n" + detail, e);
- FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR,
msg, detail);
- FacesContext.getCurrentInstance().addMessage(getPageName(), facesMsg);
+ FacesUtils.addErrorMessage(t);
}
+ /*
+ * obsolete, now in WebApplication
+ *
protected String extractErrorMessage(Throwable e)
{ // Wrap Exception
if (!(e instanceof EmpireException))
@@ -387,6 +369,7 @@ public abstract class Page // *Deprecated* implements
Serializable
}
return b.toString();
}
+ */
/**
* navigates to the desired page. Depending on the page outcome provided
this is either a forward or a redirect.
diff --git
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java
index f5b89fee..3b1c37f3 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java
@@ -23,10 +23,13 @@ import java.io.IOException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.Locale;
import java.util.Map;
import javax.el.ValueExpression;
import javax.faces.application.FacesMessage;
+import javax.faces.application.FacesMessage.Severity;
+import javax.faces.application.ProjectStage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIViewRoot;
@@ -39,7 +42,6 @@ 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.exceptions.EmpireException;
import org.apache.empire.exceptions.InternalException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.ItemNotFoundException;
@@ -47,6 +49,7 @@ 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.HtmlUtils;
import org.apache.empire.jsf2.utils.ParameterMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,6 +61,12 @@ public class FacesUtils
public static final String SKIP_INPUT_VALIDATION_PARAM =
"empire.jsf.input.skipValidation";
+ /* Develpment stage */
+ public static boolean isDevelopmentStage(final FacesContext fc)
+ {
+ return fc.getApplication().getProjectStage()==ProjectStage.Development;
+ }
+
/* App */
public static WebApplication getWebApplication()
@@ -74,6 +83,11 @@ public class FacesUtils
{
return FacesContext.getCurrentInstance();
}
+
+ public static Locale getContextLocale(final FacesContext fc)
+ {
+ return getWebApplication().getContextLocale(fc);
+ }
/* Session */
@@ -399,6 +413,16 @@ public class FacesUtils
return getWebApplication().getTextResolver(fc);
}
+ public static String resolveText(final FacesContext fc, String text)
+ {
+ return getTextResolver(fc).resolveText(text);
+ }
+
+ public static String resolveText(String text)
+ {
+ return getTextResolver(getContext()).resolveText(text);
+ }
+
public static String getMessage(final FacesContext fc, String key)
{
if (StringUtils.isEmpty(key))
@@ -412,91 +436,115 @@ public class FacesUtils
return getMessage(getContext(), messageKey);
}
- public static String formatMessage(String msgKey, Object... params)
+ public static String formatMessage(final FacesContext fc, String msgKey,
Object... params)
{
- TextResolver tr = getTextResolver(FacesContext.getCurrentInstance());
- String pattern = tr.resolveKey(msgKey);
+ String pattern = getMessage(fc, msgKey);
return MessageFormat.format(pattern, params);
}
+ public static String formatMessage(String msgKey, Object... params)
+ {
+ return formatMessage(getContext(), msgKey, params);
+ }
+
+ /**
+ * Escapes Text for Html
+ * Uses HtmlUtils.getInstance() for escaping
+ * @param text the text to escape
+ * @return the escaped text
+ */
+ public static String escapeHtml(String text)
+ {
+ return HtmlUtils.getInstance().escapeText(text);
+ }
+
/*
- public static void addInfoMessage(FacesContext fc, String clientId, String
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)
{
- fc.addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_INFO,
msg, msg));
+ Object validate =
fc.getExternalContext().getRequestMap().get("CLEAR_SUBMITTED_VALUES");
+ return (validate!=null ? ObjectUtils.getBoolean(validate) : false);
}
-
- public static void addInfoMessage(FacesContext fc, String msg)
+
+ public static void setClearSubmittedValues(FacesContext fc, boolean
validate)
{
- addInfoMessage(fc, null, msg);
+ fc.getExternalContext().getRequestMap().put("CLEAR_SUBMITTED_VALUES",
validate);
}
+ */
- public static void addWarnMessage(FacesContext fc, String clientId, String
msg)
+ public static void addFacesMessage(FacesContext fc, UIComponent comp,
FacesMessage facesMsg)
{
- fc.addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_WARN,
msg, msg));
+ if (facesMsg==null)
+ return;
+ String clientId = (comp!=null ? comp.getClientId() : null);
+ fc.addMessage(clientId, facesMsg);
}
- public static void addWarnMessage(FacesContext fc, String msg)
+ public static void addFacesMessage(UIComponent comp, Severity severity,
String message, Object... params)
{
- addWarnMessage(fc, null, msg);
+ FacesContext fc = getContext();
+ addFacesMessage(fc, comp, getWebApplication().getFacesMessage(fc,
severity, message, params));
}
- public static void addErrorMessage(FacesContext fc, String clientId,
String msg)
+ public static void addInfoMessage(String msg, Object... params)
{
- fc.addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_ERROR,
msg, msg));
+ addFacesMessage(null, FacesMessage.SEVERITY_INFO, msg, params);
}
- public static void addErrorMessage(FacesContext fc, String msg)
+ public static void addWarnMessage(String msg, Object... params)
{
- addErrorMessage(fc, null, msg);
+ addFacesMessage(null, FacesMessage.SEVERITY_WARN, msg, params);
}
- */
- /*
- * 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)
+ public static void addErrorMessage(String msg, Object... params)
{
- Object validate =
fc.getExternalContext().getRequestMap().get("CLEAR_SUBMITTED_VALUES");
- return (validate!=null ? ObjectUtils.getBoolean(validate) : false);
+ addFacesMessage(null, FacesMessage.SEVERITY_ERROR, msg, params);
}
- public static void setClearSubmittedValues(FacesContext fc, boolean
validate)
+ public static void addErrorMessage(UIComponent comp, Throwable t)
{
- fc.getExternalContext().getRequestMap().put("CLEAR_SUBMITTED_VALUES",
validate);
+ FacesContext fc = getContext();
+ addFacesMessage(fc, comp, getFacesErrorMessage(fc, t));
+ }
+
+ public static void addErrorMessage(Throwable t)
+ {
+ addErrorMessage(null, t);
}
- */
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);
+ return getWebApplication().getFacesErrorMessage(fc, null, t);
}
- public static void redirectFromError(Page page, Throwable t)
+ public static void redirectFromError(Page page, FacesMessage errorMsg)
{
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());
+ { log.warn("Cannot redirect to {} from an already committed
response! Error is {}.", pageTarget, errorMsg.getSummary());
return;
}
// redirect to target page
- FacesMessage facesMsg = getFacesErrorMessage(fc, t);
- ExternalContext ec = fc.getExternalContext();
- ec.getSessionMap().put(Page.SESSION_MESSAGE, facesMsg);
+ if (errorMsg!=null) {
+ ExternalContext ec = fc.getExternalContext();
+ ec.getSessionMap().put(Page.SESSION_MESSAGE, errorMsg);
+ }
// redirect
FacesUtils.redirectDirectly(fc, pageTarget);
}
-
+
+ public static void redirectFromError(Page page, Throwable t)
+ {
+ FacesContext fc = FacesUtils.getContext();
+ FacesMessage facesMsg = getFacesErrorMessage(fc, t);
+ redirectFromError(page, facesMsg);
+ }
/* Component search */
public static UIInput findInputComponent(UIComponent parent, Column column)
diff --git
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/WebApplication.java
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/WebApplication.java
index 694015ec..cb85d295 100644
---
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/WebApplication.java
+++
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/WebApplication.java
@@ -20,6 +20,7 @@ package org.apache.empire.jsf2.app;
import java.sql.Connection;
import java.sql.SQLException;
+import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
@@ -44,6 +45,7 @@ import org.apache.empire.data.DataType;
import org.apache.empire.db.DBDatabase;
import org.apache.empire.db.context.DBRollbackManager;
import org.apache.empire.db.context.DBRollbackManager.ReleaseAction;
+import org.apache.empire.exceptions.EmpireException;
import org.apache.empire.exceptions.InternalException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.NotSupportedException;
@@ -251,6 +253,70 @@ public abstract class WebApplication
return getTextResolver(getContextLocale(ctx));
}
+ /**
+ * Returns a FacesMessage
+ * @param ctx the FacesContext
+ * @param severity the message severity
+ * @param msg the message or message key
+ * @param params the message params
+ * @return the FacesMessage or null to ignore
+ */
+ public FacesMessage getFacesMessage(FacesContext ctx, Severity severity,
String msg, Object... params)
+ {
+ TextResolver resolver = getTextResolver(getContextLocale(ctx));
+ msg = resolver.resolveText(msg);
+ if (params.length>0)
+ { // translate params
+ for (int i=0; i<params.length; i++)
+ if (params[i] instanceof String)
+ params[i] = resolver.resolveText((String)params[i]);
+ else if ((params[i] instanceof Integer) || (params[i]
instanceof Long))
+ params[i] = String.valueOf(params[i]); // avoid group
separator
+ // format
+ msg = MessageFormat.format(msg, params);
+ }
+ return new FacesMessage(severity, msg, null);
+ }
+
+ /**
+ * Returns a FacesMessage for an Exception
+ * @param ctx the FacesContext
+ * @param errorContext the error context (optional)
+ * @param t the exception
+ * @return the FacesMessage or null to ignore
+ */
+ public FacesMessage getFacesErrorMessage(FacesContext ctx, String
errorContext, Throwable t)
+ {
+ // Wrap exception if necessary
+ EmpireException e = (t instanceof EmpireException) ?
((EmpireException)t) : new InternalException(t);
+ // Get Message
+ TextResolver tr = getTextResolver(ctx);
+ String msg = tr.getExceptionMessage(e);
+ String msgDetail = extractErrorMessageDetail(errorContext, t, 3);
+ // create Faces Message
+ return new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msgDetail);
+ }
+
+ protected String extractErrorMessageDetail(String errorContext, Throwable
e, int stackTraceElements)
+ {
+ StringBuilder b = new StringBuilder();
+ if (errorContext!=null)
+ { // Append context String
+ b.append(errorContext);
+ b.append(": ");
+ }
+ b.append(e.toString());
+ b.append("\r\nat:");
+ StackTraceElement[] stack = e.getStackTrace();
+ int len = (stack.length>stackTraceElements) ? stackTraceElements :
stack.length;
+ for (int i=0; i<len; i++)
+ {
+ b.append(stack[i].toString());
+ b.append("\r\n");
+ }
+ return b.toString();
+ }
+
/**
* checks if the current context contains an error
* @param fc the FacesContext
diff --git
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java
index aa9da2b8..c72ce4f8 100644
---
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java
+++
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/InputControl.java
@@ -791,7 +791,7 @@ public abstract class InputControl
if (hasFormatOption(vi, "noencode"))
return s;
// Encode Html
- return escapeHTML(s);
+ return escapeHtml(s);
}
/**
@@ -831,12 +831,11 @@ public abstract class InputControl
*/
/**
- * escapes a String for html
- *
- * @param text
+ * Escapes a String for html
+ * @param text the text to escape
* @return the escaped html String
*/
- protected String escapeHTML(String text)
+ protected String escapeHtml(String text)
{
return HtmlUtils.getInstance().escapeText(text);
}
diff --git
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java
index 96f4e0cd..af084acc 100644
---
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java
+++
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java
@@ -287,7 +287,7 @@ public class TextInputControl extends InputControl
return s;
// Encoded text
if (escapeHTML)
- s = escapeHTML(s);
+ s = escapeHtml(s);
return s;
}
if (dataType == DataType.INTEGER || dataType == DataType.AUTOINC)
@@ -316,7 +316,7 @@ public class TextInputControl extends InputControl
// Convert to String
if (escapeHTML)
{
- return escapeHTML(String.valueOf(value));
+ return escapeHtml(String.valueOf(value));
}
return String.valueOf(value);
}
diff --git
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java
index 31fa7cb7..a3cac649 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java
@@ -19,7 +19,6 @@
package org.apache.empire.jsf2.pages;
import java.lang.reflect.Method;
-import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -33,8 +32,6 @@ import javax.faces.context.FacesContext;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.db.DBRowSet;
-import org.apache.empire.exceptions.EmpireException;
-import org.apache.empire.exceptions.InternalException;
import org.apache.empire.exceptions.InvalidOperationException;
import org.apache.empire.exceptions.ItemNotFoundException;
import org.apache.empire.jsf2.app.FacesUtils;
@@ -289,25 +286,22 @@ public abstract class Page // *Deprecated* implements
Serializable
ec.getSessionMap().put(SESSION_MESSAGE, facesMsg);
}
- protected void setSessionError(Throwable e)
+ protected void setSessionError(Throwable t)
{
// Set Session Message
- String msg = extractErrorMessage(e);
- String detail = extractErrorMessageDetail(action, e, 1);
- if (log.isDebugEnabled())
- log.debug(msg + "\r\n" + detail, e);
- FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR,
msg, detail);
+ FacesContext fc = FacesContext.getCurrentInstance();
+ FacesMessage facesMsg = FacesUtils.getFacesErrorMessage(fc, t);
setSessionMessage(facesMsg);
}
- protected boolean handleActionError(String action, Throwable e)
+ protected boolean handleActionError(String action, Throwable t)
{
- // Set Faces Message
- String msg = extractErrorMessage(e);
- String detail = extractErrorMessageDetail(action, e, 1);
- // log.error(msg + "\r\n" + detail);
- FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR,
msg, detail);
- setSessionMessage(facesMsg);
+ // the error context
+ String errorContext = StringUtils.concat(getPageName(), ":", action);
+ // get Message
+ WebApplication app = FacesUtils.getWebApplication();
+ FacesContext fc = FacesContext.getCurrentInstance();
+ FacesMessage facesMsg = app.getFacesErrorMessage(fc, errorContext, t);
// Return to parent page
PageDefinition parentPage = getParentPage();
if (parentPage == null)
@@ -315,24 +309,14 @@ public abstract class Page // *Deprecated* implements
Serializable
return false;
}
// redirect
+ setSessionMessage(facesMsg);
navigateTo(parentPage.getRedirect());
return true;
}
protected void addFacesMessage(Severity severity, String msg, Object...
params)
{
- TextResolver resolver = getTextResolver();
- msg = resolver.resolveText(msg);
- if (params.length>0)
- { // translate params
- for (int i=0; i<params.length; i++)
- if (params[i] instanceof String)
- params[i] = resolver.resolveText((String)params[i]);
- // format
- msg = MessageFormat.format(msg, params);
- }
- FacesMessage facesMsg = new FacesMessage(severity, msg, msg);
- FacesContext.getCurrentInstance().addMessage(getPageName(), facesMsg);
+ FacesUtils.addFacesMessage(null, severity, msg, params);
}
public final void addInfoMessage(String msg, Object... params)
@@ -350,16 +334,14 @@ public abstract class Page // *Deprecated* implements
Serializable
addFacesMessage(FacesMessage.SEVERITY_ERROR, msg, params);
}
- public void setErrorMessage(Throwable e)
+ public void setErrorMessage(Throwable t)
{
- String msg = extractErrorMessage(e);
- String detail = extractErrorMessageDetail(action, e, 1);
- if (log.isDebugEnabled())
- log.debug(msg + "\r\n" + detail, e);
- FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR,
msg, detail);
- FacesContext.getCurrentInstance().addMessage(getPageName(), facesMsg);
+ FacesUtils.addErrorMessage(t);
}
+ /*
+ * obsolete, now in WebApplication
+ *
protected String extractErrorMessage(Throwable e)
{ // Wrap Exception
if (!(e instanceof EmpireException))
@@ -387,6 +369,7 @@ public abstract class Page // *Deprecated* implements
Serializable
}
return b.toString();
}
+ */
/**
* navigates to the desired page. Depending on the page outcome provided
this is either a forward or a redirect.