[seam-commits] Seam SVN: r10601 - in modules/trunk: faces and 8 other directories.
seam-commits at lists.jboss.org
seam-commits at lists.jboss.org
Wed Apr 22 21:09:20 EDT 2009
Author: shane.bryzak at jboss.com
Date: 2009-04-22 21:09:20 -0400 (Wed, 22 Apr 2009)
New Revision: 10601
Added:
modules/trunk/faces/
modules/trunk/faces/pom.xml
modules/trunk/faces/src/
modules/trunk/faces/src/main/
modules/trunk/faces/src/main/java/
modules/trunk/faces/src/main/java/org/
modules/trunk/faces/src/main/java/org/jboss/
modules/trunk/faces/src/main/java/org/jboss/seam/
modules/trunk/faces/src/main/java/org/jboss/seam/faces/
modules/trunk/faces/src/main/java/org/jboss/seam/faces/DataModels.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/DateConverter.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesContext.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesExpressions.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesManager.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesMessages.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesPage.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/HttpError.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/IsUserInRole.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/Navigator.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/Parameters.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/Redirect.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/RedirectException.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/Renderer.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/ResourceLoader.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/Selector.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/Switcher.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/UiComponent.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/UserPrincipal.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/Validation.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/events/
modules/trunk/faces/src/main/java/org/jboss/seam/faces/events/ValidationFailedEvent.java
modules/trunk/faces/src/main/java/org/jboss/seam/faces/package-info.java
Log:
initial import of faces module
Added: modules/trunk/faces/pom.xml
===================================================================
--- modules/trunk/faces/pom.xml (rev 0)
+++ modules/trunk/faces/pom.xml 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,36 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>seam-parent</artifactId>
+ <groupId>org.jboss.seam</groupId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>seam-faces</artifactId>
+ <packaging>jar</packaging>
+ <version>3.0.0-SNAPSHOT</version>
+ <name>Seam Faces</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.webbeans</groupId>
+ <artifactId>jsr299-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/DataModels.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/DataModels.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/DataModels.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,70 @@
+package org.jboss.seam.faces;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.faces.model.DataModel;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.framework.Query;
+import org.jboss.seam.jsf.ArrayDataModel;
+import org.jboss.seam.jsf.ListDataModel;
+import org.jboss.seam.jsf.MapDataModel;
+import org.jboss.seam.jsf.SetDataModel;
+
+/**
+ * Wraps a collection as a JSF {@link DataModel}. May be overridden
+ * and extended if you don't like the built in collections
+ * which are supported: list, map, set, array.
+ *
+ * @author pmuir
+ */
+public class DataModels
+{
+
+ /**
+ * Wrap the value in a DataModel
+ *
+ * This implementation supports {@link List}, {@link Map}, {@link Set} and
+ * arrays
+ */
+ public DataModel getDataModel(Object value)
+ {
+ if (value instanceof List)
+ {
+ return new ListDataModel( (List) value );
+ }
+ else if (value instanceof Object[])
+ {
+ return new ArrayDataModel( (Object[]) value );
+ }
+ else if (value instanceof Map)
+ {
+ return new MapDataModel( (Map) value );
+ }
+ else if (value instanceof Set)
+ {
+ return new SetDataModel( (Set) value );
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown collection type: " + value.getClass());
+ }
+ }
+
+ /**
+ * Wrap the the Seam Framework {@link Query} in a JSF DataModel
+ */
+ public DataModel getDataModel(Query query)
+ {
+ return getDataModel( query.getResultList() );
+ }
+
+ public static DataModels instance()
+ {
+ return (DataModels) Component.getInstance(DataModels.class, ScopeType.STATELESS);
+ }
+
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/DateConverter.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/DateConverter.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/DateConverter.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,120 @@
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.ConverterException;
+
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.faces.Converter;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+
+/**
+ * Provides a default JSF converter for properties of type java.util.Date.
+ *
+ * <p>This converter is provided to save a developer from having to specify
+ * a DateTimeConverter on an input field or page parameter. By default, it
+ * assumes the type to be a date (as opposed to a time or date plus time) and
+ * uses the short input style adjusted to the Locale of the user. For Locale.US,
+ * the input pattern is mm/DD/yy. However, to comply with Y2K, the year is changed
+ * from two digits to four (e.g., mm/DD/yyyy).</p>
+ * <p>It's possible to override the input pattern globally using component configuration.
+ * Here is an example of changing the style to both and setting the date and
+ * time style to medium.</p>
+ * <pre>
+ * org.jboss.seam.faces.dateConverter.type=both
+ * org.jboss.seam.faces.dateConverter.dateStyle=medium
+ * org.jboss.seam.faces.dateConverter.timeStyle=medium
+ * </pre>
+ * <p>Alternatively, a fixed pattern can be specified.</p>
+ * <pre>
+ * org.jboss.seam.faces.dateConverter.pattern=yyyy-mm-DD
+ * </pre>
+ *
+ * @author Dan Allen
+ */
+ at Converter(forClass = Date.class)
+ at Name("org.jboss.seam.faces.dateConverter")
+ at Install(precedence = BUILT_IN, classDependencies = "javax.faces.context.FacesContext")
+ at BypassInterceptors
+public class DateConverter extends javax.faces.convert.DateTimeConverter {
+
+ private Log log = Logging.getLog(DateConverter.class);
+
+ private static final String TYPE_DATE = "date";
+ private static final String STYLE_SHORT = "short";
+ private static final String TWO_DIGIT_YEAR_PATTERN = "yy";
+ private static final String FOUR_DIGIT_YEAR_PATTERN = "yyyy";
+
+ // constructor is used to initialize converter to allow these values to be overridden using component properties
+ public DateConverter() {
+ super();
+ setType(TYPE_DATE);
+ setDateStyle(STYLE_SHORT);
+ setTimeStyle(STYLE_SHORT); // default in case developer overrides type to be time or both
+ }
+
+ @Create
+ public void create() {
+ // TODO make this work if using "both" for type; requires more analysis of time style
+ if (TYPE_DATE.equals(getType()) && STYLE_SHORT.equals(getDateStyle()) && getPattern() == null) {
+ // attempt to make the pattern Y2K compliant, which it isn't by default
+ DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, getLocale());
+ if (dateFormat instanceof SimpleDateFormat) {
+ setPattern(((SimpleDateFormat) dateFormat).toPattern().replace(TWO_DIGIT_YEAR_PATTERN, FOUR_DIGIT_YEAR_PATTERN));
+ }
+ }
+ // required since the superclass may access the fields directly
+ setTimeZone(getTimeZone());
+ setLocale(getLocale());
+ }
+
+ @Override
+ public TimeZone getTimeZone() {
+ if (Contexts.isApplicationContextActive()) {
+ return org.jboss.seam.international.TimeZone.instance();
+ } else {
+ // we don't want to use JSF's braindead default (maybe in JSF 2)
+ return TimeZone.getDefault();
+ }
+ }
+
+ @Override
+ public Locale getLocale() {
+ if (Contexts.isApplicationContextActive()) {
+ return org.jboss.seam.international.Locale.instance();
+ } else {
+ return super.getLocale();
+ }
+ }
+
+ @Override
+ public Object getAsObject(FacesContext context, UIComponent component,
+ String value) throws ConverterException {
+ if (log.isDebugEnabled()) {
+ log.debug("Converting string '#0' to date for clientId '#1' using Seam's built-in JSF date converter", value, component.getClientId(context));
+ }
+ return super.getAsObject(context, component, value);
+ }
+
+ @Override
+ public String getAsString(FacesContext context, UIComponent component,
+ Object value) throws ConverterException {
+ if (log.isDebugEnabled()) {
+ log.debug("Converting date '#0' to string for clientId '#1' using Seam's built-in JSF date converter", value, component.getClientId(context));
+ }
+ return super.getAsString(context, component, value);
+ }
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesContext.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesContext.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesContext.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,29 @@
+//$Id: FacesContext.java 5350 2007-06-20 17:53:19Z gavin $
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Unwrap;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+
+/**
+ * Support for injecting the JSF FacesContext object
+ *
+ * @author Gavin King
+ */
+ at Scope(ScopeType.APPLICATION)
+ at BypassInterceptors
+ at Name("org.jboss.seam.faces.facesContext")
+ at Install(precedence=BUILT_IN, classDependencies="javax.faces.context.FacesContext")
+public class FacesContext
+{
+ @Unwrap
+ public javax.faces.context.FacesContext getContext()
+ {
+ return javax.faces.context.FacesContext.getCurrentInstance();
+ }
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesExpressions.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesExpressions.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesExpressions.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,37 @@
+//$Id: FacesExpressions.java 9684 2008-12-01 21:41:20Z dan.j.allen $
+package org.jboss.seam.faces;
+
+import javax.annotation.Named;
+import javax.context.ApplicationScoped;
+import javax.el.ELContext;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.contexts.FacesLifecycle;
+import org.jboss.seam.core.Expressions;
+
+/**
+ * Factory for method and value bindings in a JSF environment.
+ *
+ * @author Gavin King
+ */
+ at Named
+ at ApplicationScoped
+public class FacesExpressions extends Expressions
+{
+ /**
+ * Get an appropriate ELContext. If there is an active JSF request,
+ * use JSF's ELContext. Otherwise, use one that we created.
+ */
+ @Override
+ public ELContext getELContext()
+ {
+ return isFacesContextActive() ? FacesContext.getCurrentInstance().getELContext() : super.getELContext();
+ }
+
+ @Override
+ protected boolean isFacesContextActive()
+ {
+ return FacesContext.getCurrentInstance() != null && FacesLifecycle.getPhaseId() != null;
+ }
+
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesManager.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesManager.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesManager.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,316 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.annotations.Install.FRAMEWORK;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.contexts.FacesLifecycle;
+import org.jboss.seam.core.Conversation;
+import org.jboss.seam.core.Init;
+import org.jboss.seam.core.Interpolator;
+import org.jboss.seam.core.Manager;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+import org.jboss.seam.navigation.ConversationIdParameter;
+import org.jboss.seam.navigation.Pages;
+import org.jboss.seam.pageflow.Pageflow;
+
+/**
+ * An extended conversation manager for the JSF environment.
+ *
+ * @author Gavin King
+ * @author <a href="mailto:theute at jboss.org">Thomas Heute</a>
+ */
+ at Scope(ScopeType.EVENT)
+ at Name("org.jboss.seam.core.manager")
+ at Install(precedence=FRAMEWORK, classDependencies="javax.faces.context.FacesContext")
+ at BypassInterceptors
+public class FacesManager extends Manager
+{
+ private static final LogProvider log = Logging.getLogProvider(FacesManager.class);
+
+
+
+ private boolean controllingRedirect;
+
+ /**
+ * Temporarily promote a temporary conversation to
+ * a long running conversation for the duration of
+ * a browser redirect. After the redirect, the
+ * conversation will be demoted back to a temporary
+ * conversation. Handle any changes to the conversation
+ * id, due to propagation via natural id.
+ */
+ public void beforeRedirect(String viewId)
+ {
+ beforeRedirect();
+
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ String currentViewId = Pages.getViewId(facesContext);
+ if ( viewId!=null && currentViewId!=null )
+ {
+ ConversationIdParameter currentPage = Pages.instance().getPage(currentViewId).getConversationIdParameter();
+ ConversationIdParameter targetPage = Pages.instance().getPage(viewId).getConversationIdParameter();
+ if ( isDifferentConversationId(currentPage, targetPage) )
+ {
+ updateCurrentConversationId( targetPage.getConversationId() );
+ }
+ }
+ }
+
+ public void interpolateAndRedirect(String url)
+ {
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ int loc = url.indexOf('?');
+ if (loc>0)
+ {
+ StringTokenizer tokens = new StringTokenizer( url.substring(loc), "?=&" );
+ while ( tokens.hasMoreTokens() )
+ {
+ String name = tokens.nextToken();
+ String value = Interpolator.instance().interpolate( tokens.nextToken() );
+ parameters.put(name, value);
+ }
+ url = url.substring(0, loc);
+ }
+ redirect(url, parameters, true, true);
+ }
+
+ @Override
+ protected void storeConversationToViewRootIfNecessary()
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ if ( facesContext!=null && FacesLifecycle.getPhaseId()==PhaseId.RENDER_RESPONSE )
+ {
+ FacesPage.instance().storeConversation();
+ }
+ }
+
+ @Override
+ protected String generateInitialConversationId()
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ String viewId = Pages.getViewId(facesContext);
+ if ( viewId!=null )
+ {
+ return Pages.instance().getPage(viewId)
+ .getConversationIdParameter()
+ .getInitialConversationId( facesContext.getExternalContext().getRequestParameterMap() );
+ }
+ else
+ {
+ return super.generateInitialConversationId();
+ }
+ }
+
+ public void redirectToExternalURL(String url) {
+ try {
+ FacesContext.getCurrentInstance().getExternalContext().redirect(url);
+ } catch (IOException e) {
+ throw new RedirectException(e);
+ }
+ }
+
+ /**
+ * Redirect to the given view id, encoding the conversation id
+ * into the request URL.
+ *
+ * @param viewId the JSF view id
+ */
+ @Override
+ public void redirect(String viewId)
+ {
+ redirect(viewId, null, true, true);
+ }
+
+ public void redirect(String viewId, Map<String, Object> parameters,
+ boolean includeConversationId)
+ {
+ redirect(viewId, parameters, includeConversationId, true);
+ }
+
+ /**
+ * Redirect to the given view id, after encoding parameters and conversation
+ * id into the request URL.
+ *
+ * @param viewId the JSF view id
+ * @param parameters request parameters to be encoded (possibly null)
+ * @param includeConversationId determines if the conversation id is to be encoded
+ */
+ public void redirect(String viewId, Map<String, Object> parameters,
+ boolean includeConversationId, boolean includePageParams)
+ {
+ if (viewId == null)
+ {
+ throw new RedirectException("cannot redirect to a null viewId");
+ }
+ FacesContext context = FacesContext.getCurrentInstance();
+ String url = context.getApplication().getViewHandler().getActionURL(context, viewId);
+ if (parameters!=null)
+ {
+ url = encodeParameters(url, parameters);
+ }
+
+ if (includePageParams)
+ {
+ url = Pages.instance().encodePageParameters(FacesContext.getCurrentInstance(),
+ url, viewId, parameters==null ? Collections.EMPTY_SET : parameters.keySet());
+ }
+
+ if (includeConversationId)
+ {
+ beforeRedirect(viewId);
+ url = encodeConversationId(url, viewId);
+ }
+ redirect(viewId, context, url);
+ }
+
+ /**
+ * Redirect to the given view id, after encoding the given conversation
+ * id into the request URL.
+ *
+ * @param viewId the JSF view id
+ * @param conversationId an id of a long-running conversation
+ */
+ @Override
+ public void redirect(String viewId, String conversationId)
+ {
+ if (viewId == null)
+ {
+ throw new RedirectException("cannot redirect to a null viewId");
+ }
+ FacesContext context = FacesContext.getCurrentInstance();
+ String url = context.getApplication().getViewHandler().getActionURL(context, viewId);
+ url = encodeConversationId(url, viewId, conversationId);
+ redirect(viewId, context, url);
+ }
+
+ private void redirect(String viewId, FacesContext context, String url)
+ {
+ url = Pages.instance().encodeScheme(viewId, context, url);
+ if ( log.isDebugEnabled() )
+ {
+ log.debug("redirecting to: " + url);
+ }
+ ExternalContext externalContext = context.getExternalContext();
+ controllingRedirect = true;
+ try
+ {
+ Contexts.getEventContext().set(REDIRECT_FROM_MANAGER, "");
+ externalContext.redirect( externalContext.encodeActionURL(url) );
+ }
+ catch (IOException ioe)
+ {
+ throw new RedirectException(ioe);
+ }
+ finally
+ {
+ Contexts.getEventContext().remove(REDIRECT_FROM_MANAGER);
+ controllingRedirect = false;
+ }
+ context.responseComplete();
+ }
+
+ /**
+ * Called by the Seam Redirect Filter when a redirect is called.
+ * Appends the conversationId parameter if necessary.
+ *
+ * @param url the requested URL
+ * @return the resulting URL with the conversationId appended
+ */
+ public String appendConversationIdFromRedirectFilter(String url, String viewId)
+ {
+ boolean appendConversationId = !controllingRedirect;
+ if (appendConversationId)
+ {
+ beforeRedirect(viewId);
+ url = encodeConversationId(url, viewId);
+ }
+ return url;
+ }
+
+ /**
+ * If a page description is defined, remember the description and
+ * view id for the current page, to support conversation switching.
+ * Called just before the render phase.
+ */
+ public void prepareBackswitch(FacesContext facesContext)
+ {
+
+ Conversation conversation = Conversation.instance();
+
+ //stuff from jPDL takes precedence
+ org.jboss.seam.pageflow.Page page =
+ Manager.instance().isLongRunningConversation() &&
+ Init.instance().isJbpmInstalled() &&
+ Pageflow.instance().isInProcess() && Pageflow.instance().isStarted() ?
+ Pageflow.instance().getPage() : null;
+
+ if (page==null)
+ {
+ //handle stuff defined in pages.xml
+ Pages pages = Pages.instance();
+ if (pages!=null) //for tests
+ {
+ String viewId = Pages.getViewId(facesContext);
+ org.jboss.seam.navigation.Page pageEntry = pages.getPage(viewId);
+ if ( pageEntry.isSwitchEnabled() )
+ {
+ conversation.setViewId(viewId);
+ }
+ if ( pageEntry.hasDescription() )
+ {
+ conversation.setDescription( pageEntry.renderDescription() );
+ }
+ else if(pages.hasDescription(viewId))
+ {
+ conversation.setDescription( pages.renderDescription(viewId) );
+ }
+ conversation.setTimeout( pages.getTimeout(viewId) );
+ conversation.setConcurrentRequestTimeout( pages.getConcurrentRequestTimeout(viewId) );
+ }
+ }
+ else
+ {
+ //use stuff from the pageflow definition
+ if ( page.isSwitchEnabled() )
+ {
+ conversation.setViewId( Pageflow.instance().getPageViewId() );
+ }
+ if ( page.hasDescription() )
+ {
+ conversation.setDescription( page.getDescription() );
+ }
+ conversation.setTimeout( page.getTimeout() );
+ }
+
+ flushConversationMetadata();
+
+ }
+
+ public static FacesManager instance()
+ {
+ return (FacesManager) Manager.instance();
+ }
+
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesMessages.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesMessages.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesMessages.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,356 @@
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.international.StatusMessage;
+import org.jboss.seam.international.StatusMessages;
+import org.jboss.seam.util.Strings;
+
+/**
+ * A Seam component that propagates FacesMessages across redirects
+ * and interpolates EL expressions in the message string.
+ *
+ * @author Gavin King
+ * @author Pete Muir
+ */
+ at Scope(ScopeType.CONVERSATION)
+ at Name(StatusMessages.COMPONENT_NAME)
+ at Install(precedence=BUILT_IN, classDependencies="javax.faces.context.FacesContext")
+ at BypassInterceptors
+public class FacesMessages extends StatusMessages
+{
+
+ /**
+ * Called by Seam to transfer messages from FacesMessages to JSF
+ */
+ public void beforeRenderResponse()
+ {
+ for (StatusMessage statusMessage: getMessages())
+ {
+ FacesContext.getCurrentInstance().addMessage( null, toFacesMessage(statusMessage) );
+ }
+ for ( Map.Entry<String, List<StatusMessage>> entry: getKeyedMessages().entrySet() )
+ {
+ for ( StatusMessage statusMessage: entry.getValue() )
+ {
+ String clientId = getClientId(entry.getKey());
+ FacesContext.getCurrentInstance().addMessage( clientId, toFacesMessage(statusMessage) );
+ }
+ }
+ clear();
+ }
+
+ /**
+ * Called by Seam to transfer any messages added in the phase just processed
+ * to the FacesMessages component.
+ *
+ * A task runner is used to allow the messages access to outjected values.
+ */
+ public static void afterPhase()
+ {
+ runTasks();
+ }
+
+ /**
+ * Convert a StatusMessage to a FacesMessage
+ */
+ private static FacesMessage toFacesMessage(StatusMessage statusMessage)
+ {
+ if (!Strings.isEmpty(statusMessage.getSummary()))
+ {
+ return new FacesMessage(toSeverity(statusMessage.getSeverity()), statusMessage.getSummary(), statusMessage.getDetail() );
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Convert a StatusMessage.Severity to a FacesMessage.Severity
+ */
+ private static javax.faces.application.FacesMessage.Severity toSeverity(org.jboss.seam.international.StatusMessage.Severity severity)
+ {
+ switch (severity)
+ {
+ case ERROR:
+ return FacesMessage.SEVERITY_ERROR;
+ case FATAL:
+ return FacesMessage.SEVERITY_FATAL;
+ case INFO:
+ return FacesMessage.SEVERITY_INFO;
+ case WARN:
+ return FacesMessage.SEVERITY_WARN;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Convert a FacesMessage.Severity to a StatusMessage.Severity
+ */
+ private static org.jboss.seam.international.StatusMessage.Severity toSeverity(javax.faces.application.FacesMessage.Severity severity)
+ {
+ if (FacesMessage.SEVERITY_ERROR.equals(severity))
+ {
+ return org.jboss.seam.international.StatusMessage.Severity.ERROR;
+ }
+ else if (FacesMessage.SEVERITY_FATAL.equals(severity))
+ {
+ return org.jboss.seam.international.StatusMessage.Severity.FATAL;
+ }
+ else if (FacesMessage.SEVERITY_INFO.equals(severity))
+ {
+ return org.jboss.seam.international.StatusMessage.Severity.INFO;
+ }
+ else if (FacesMessage.SEVERITY_WARN.equals(severity))
+ {
+ return org.jboss.seam.international.StatusMessage.Severity.WARN;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Calculate the JSF client ID from the provided widget ID
+ */
+ private String getClientId(String id)
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ return getClientId( facesContext.getViewRoot(), id, facesContext);
+ }
+
+ private static String getClientId(UIComponent component, String id, FacesContext facesContext)
+ {
+ String componentId = component.getId();
+ if (componentId!=null && componentId.equals(id))
+ {
+ return component.getClientId(facesContext);
+ }
+ else
+ {
+ Iterator iter = component.getFacetsAndChildren();
+ while ( iter.hasNext() )
+ {
+ UIComponent child = (UIComponent) iter.next();
+ String clientId = getClientId(child, id, facesContext);
+ if (clientId!=null) return clientId;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Get all faces messages that have already been added
+ * to the context.
+ *
+ */
+ public List<FacesMessage> getCurrentMessages()
+ {
+ List<FacesMessage> result = new ArrayList<FacesMessage>();
+ Iterator<FacesMessage> iter = FacesContext.getCurrentInstance().getMessages();
+ while ( iter.hasNext() )
+ {
+ result.add( iter.next() );
+ }
+ return result;
+ }
+
+ /**
+ * Get all faces global messages that have already been added
+ * to the context.
+ *
+ */
+ public List<FacesMessage> getCurrentGlobalMessages()
+ {
+ List<FacesMessage> result = new ArrayList<FacesMessage>();
+ Iterator<FacesMessage> iter = FacesContext.getCurrentInstance().getMessages(null);
+ while ( iter.hasNext() )
+ {
+ result.add( iter.next() );
+ }
+ return result;
+ }
+
+ /**
+ * Get all faces messages that have already been added
+ * to the control.
+ *
+ */
+ public List<FacesMessage> getCurrentMessagesForControl(String id)
+ {
+ String clientId = getClientId(id);
+ List<FacesMessage> result = new ArrayList<FacesMessage>();
+ Iterator<FacesMessage> iter = FacesContext.getCurrentInstance().getMessages(clientId);
+ while ( iter.hasNext() )
+ {
+ result.add( iter.next() );
+ }
+ return result;
+ }
+
+ /**
+ * Utility method to create a FacesMessage from a Severity, messageTemplate
+ * and params.
+ *
+ * This method interpolates the parameters provided
+ */
+ public static FacesMessage createFacesMessage(javax.faces.application.FacesMessage.Severity severity, String messageTemplate, Object... params)
+ {
+ return createFacesMessage(severity, null, messageTemplate, params);
+ }
+
+ /**
+ * Utility method to create a FacesMessage from a Severity, key,
+ * defaultMessageTemplate and params.
+ *
+ * This method interpolates the parameters provided
+ */
+ public static FacesMessage createFacesMessage(javax.faces.application.FacesMessage.Severity severity, String key, String defaultMessageTemplate, Object... params)
+ {
+ StatusMessage message = new StatusMessage(toSeverity(severity), key, null, defaultMessageTemplate, null);
+ message.interpolate(params);
+ return toFacesMessage(message);
+ }
+
+ /**
+ * Add a FacesMessage that will be used
+ * the next time a page is rendered.
+ *
+ * Deprecated, use a method in {@link StatusMessages} instead
+ */
+ @Deprecated
+ public void add(FacesMessage facesMessage)
+ {
+ if (facesMessage!=null)
+ {
+ add(toSeverity(facesMessage.getSeverity()), null, null, facesMessage.getSummary(), facesMessage.getDetail());
+ }
+ }
+
+ /**
+ * Create a new status message, with the messageTemplate is as the message.
+ *
+ * You can also specify the severity, and parameters to be interpolated
+ *
+ * Deprecated, use {@link #add(org.jboss.seam.international.StatusMessage.Severity, String, Object...)}
+ * instead
+ */
+ @Deprecated
+ public void add(javax.faces.application.FacesMessage.Severity severity, String messageTemplate, Object... params)
+ {
+ add(toSeverity(severity), messageTemplate, params);
+ }
+
+
+ /**
+ * Create a new status message, with the messageTemplate is as the message.
+ *
+ * A severity of INFO will be used, and you can specify paramters to be
+ * interpolated
+ *
+ * Deprecated, use {@link #addToControl(String, org.jboss.seam.international.StatusMessage.Severity, String, Object...)}
+ * instead
+ */
+ @Deprecated
+ public void addToControl(String id, javax.faces.application.FacesMessage.Severity severity, String messageTemplate, Object... params)
+ {
+ addToControl(id, toSeverity(severity), messageTemplate, params);
+ }
+
+ /**
+ * Add a status message, looking up the message in the resource bundle
+ * using the provided key.
+ *
+ * You can also specify the severity, and parameters to be interpolated
+ *
+ * Deprecated, use {@link #addFromResourceBundle(org.jboss.seam.international.StatusMessage.Severity, String, Object...)}
+ * instead
+ */
+ @Deprecated
+ public void addFromResourceBundle(javax.faces.application.FacesMessage.Severity severity, String key, Object... params)
+ {
+ addFromResourceBundle(toSeverity(severity), key, params);
+ }
+
+ /**
+ * Add a status message, looking up the message in the resource bundle
+ * using the provided key.
+ *
+ * You can also specify the severity, and parameters to be interpolated
+ *
+ * Deprecated, use {@link #addFromResourceBundleOrDefault(javax.faces.application.FacesMessage.Severity, String, String, Object...)}
+ * instead
+ */
+ @Deprecated
+ public void addFromResourceBundleOrDefault(javax.faces.application.FacesMessage.Severity severity, String key, String defaultMessageTemplate, Object... params)
+ {
+ addFromResourceBundleOrDefault(toSeverity(severity), key, defaultMessageTemplate, params);
+ }
+
+ /**
+ * Create a new status message, looking up the message in the resource bundle
+ * using the provided key.
+ *
+ * The message will be added to the widget specified by the ID. The algorithm
+ * used determine which widget the id refers to is determined by the view
+ * layer implementation in use.
+ *
+ * You can also specify the severity, and parameters to be interpolated
+ *
+ * Deprecated, use {@link #addToControlFromResourceBundle(String, org.jboss.seam.international.StatusMessage.Severity, String, Object...)}
+ * instead
+ */
+ @Deprecated
+ public void addToControlFromResourceBundle(String id, javax.faces.application.FacesMessage.Severity severity, String key, Object... params)
+ {
+ addToControlFromResourceBundle(id, toSeverity(severity), key, params);
+ }
+
+ /**
+ * Add a status message, looking up the message in the resource bundle
+ * using the provided key. If the message is found, it is used, otherwise,
+ * the defaultMessageTemplate will be used.
+ *
+ * The message will be added to the widget specified by the ID. The algorithm
+ * used determine which widget the id refers to is determined by the view
+ * layer implementation in use.
+ *
+ * You can also specify the severity, and parameters to be interpolated
+ *
+ * Deprecated, use {@link #addToControlFromResourceBundleOrDefault(String, org.jboss.seam.international.StatusMessage.Severity, String, String, Object...)}
+ * instead
+ */
+ @Deprecated
+ public void addToControlFromResourceBundleOrDefault(String id, javax.faces.application.FacesMessage.Severity severity, String key, String defaultMessageTemplate, Object... params)
+ {
+ addToControlFromResourceBundleOrDefault(id, toSeverity(severity), key, defaultMessageTemplate, params);
+ }
+
+ public static FacesMessages instance()
+ {
+ if ( !Contexts.isConversationContextActive() )
+ {
+ throw new IllegalStateException("No active conversation context");
+ }
+ return (FacesMessages) Component.getInstance(StatusMessages.COMPONENT_NAME, ScopeType.CONVERSATION);
+ }
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesPage.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesPage.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesPage.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,173 @@
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.io.Serializable;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.core.Init;
+import org.jboss.seam.core.Manager;
+import org.jboss.seam.pageflow.Pageflow;
+import org.jboss.seam.web.Session;
+
+/**
+ * Book-keeping component that persists information
+ * about the conversation associated with the current
+ * page.
+ *
+ * @author Gavin King
+ *
+ */
+ at Name("org.jboss.seam.faces.facesPage")
+ at BypassInterceptors
+ at Install(precedence=BUILT_IN, classDependencies="javax.faces.context.FacesContext")
+ at Scope(ScopeType.PAGE)
+public class FacesPage implements Serializable
+{
+ private static final long serialVersionUID = 4807114041808347239L;
+ private String pageflowName;
+ private Integer pageflowCounter;
+ private String pageflowNodeName;
+
+ private String conversationId;
+ private boolean conversationIsLongRunning;
+
+ //private Map<String, Object> pageParameters;
+
+ public String getConversationId()
+ {
+ return conversationId;
+ }
+
+ public void discardTemporaryConversation()
+ {
+ conversationId = null;
+ conversationIsLongRunning = false;
+ }
+
+ public void discardNestedConversation(String outerConversationId)
+ {
+ conversationId = outerConversationId;
+ conversationIsLongRunning = true;
+ }
+
+ public void storeConversation(String conversationId)
+ {
+ this.conversationId = conversationId;
+ conversationIsLongRunning = true;
+ }
+
+ public void storePageflow()
+ {
+ if ( Init.instance().isJbpmInstalled() )
+ {
+ Pageflow pageflow = Pageflow.instance();
+ if ( pageflow.isInProcess() /*&& !pageflow.getProcessInstance().hasEnded()*/ && Manager.instance().isLongRunningConversation() )
+ {
+ pageflowName = pageflow.getSubProcessInstance().getProcessDefinition().getName();
+ pageflowNodeName = pageflow.getNode().getName();
+ pageflowCounter = pageflow.getPageflowCounter();
+ }
+ else
+ {
+ pageflowName = null;
+ pageflowNodeName = null;
+ pageflowCounter = null;
+ }
+ }
+ }
+
+ public static FacesPage instance()
+ {
+ if ( !Contexts.isPageContextActive() )
+ {
+ throw new IllegalStateException("No page context active");
+ }
+ return (FacesPage) Component.getInstance(FacesPage.class, ScopeType.PAGE);
+ }
+
+ public boolean isConversationLongRunning()
+ {
+ return conversationIsLongRunning;
+ }
+
+ public Integer getPageflowCounter()
+ {
+ return pageflowCounter;
+ }
+
+ public String getPageflowName()
+ {
+ return pageflowName;
+ }
+
+ public String getPageflowNodeName()
+ {
+ return pageflowNodeName;
+ }
+
+ public void storeConversation()
+ {
+ Manager manager = Manager.instance();
+
+ //we only need to execute this code when we are in the
+ //RENDER_RESPONSE phase, ie. not before redirects
+
+ Session session = Session.getInstance();
+ boolean sessionInvalid = session!=null && session.isInvalid();
+ if ( !sessionInvalid && manager.isLongRunningConversation() )
+ {
+ storeConversation( manager.getCurrentConversationId() );
+ }
+ else if ( !sessionInvalid && manager.isNestedConversation() )
+ {
+ discardNestedConversation( manager.getParentConversationId() );
+ }
+ else
+ {
+ discardTemporaryConversation();
+ }
+
+ /*if ( !sessionInvalid && Init.instance().isClientSideConversations() )
+ {
+ // if we are using client-side conversations, put the
+ // map containing the conversation context variables
+ // into the view root (or remove it for a temp
+ // conversation context)
+ Contexts.getConversationContext().flush();
+ }*/
+
+ }
+
+ /*public Map<String, Object> getPageParameters()
+ {
+ return pageParameters==null ? Collections.EMPTY_MAP : pageParameters;
+ }
+
+ public void setPageParameters(Map<String, Object> pageParameters)
+ {
+ this.pageParameters = pageParameters.isEmpty() ? null : pageParameters;
+ }
+
+ /**
+ * Used by test harness
+ *
+ * @param name the page parameter name
+ * @param value the value
+ */
+ /*public void setPageParameter(String name, Object value)
+ {
+ if (pageParameters==null)
+ {
+ pageParameters = new HashMap<String, Object>();
+ }
+ pageParameters.put(name, value);
+ }*/
+
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/HttpError.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/HttpError.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/HttpError.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,76 @@
+//$Id: HttpError.java 5350 2007-06-20 17:53:19Z gavin $
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.io.IOException;
+
+import javax.faces.context.FacesContext;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+
+/**
+ * Convenient HTTP errors
+ *
+ * @author Gavin King
+ */
+ at Scope(ScopeType.APPLICATION)
+ at BypassInterceptors
+ at Name("org.jboss.seam.faces.httpError")
+ at Install(precedence=BUILT_IN, classDependencies="javax.faces.context.FacesContext")
+public class HttpError
+{
+ /**
+ * Send a HTTP error as the response
+ */
+ public void send(int code)
+ {
+ try
+ {
+ getResponse().sendError(code);
+ }
+ catch (IOException ioe)
+ {
+ throw new IllegalStateException(ioe);
+ }
+ FacesContext.getCurrentInstance().responseComplete();
+ }
+
+ /**
+ * Send a HTTP error as the response
+ */
+ public void send(int code, String message)
+ {
+ try
+ {
+ getResponse().sendError(code, message);
+ }
+ catch (IOException ioe)
+ {
+ throw new IllegalStateException(ioe);
+ }
+ FacesContext.getCurrentInstance().responseComplete();
+ }
+
+ private static HttpServletResponse getResponse()
+ {
+ return (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
+ }
+
+ public static HttpError instance()
+ {
+ if ( !Contexts.isApplicationContextActive() )
+ {
+ throw new IllegalStateException("No active application scope");
+ }
+ return (HttpError) Component.getInstance(HttpError.class, ScopeType.APPLICATION);
+ }
+
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/IsUserInRole.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/IsUserInRole.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/IsUserInRole.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,37 @@
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.annotations.Install.FRAMEWORK;
+
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+
+/**
+ * Manager component for a map of roles assigned
+ * to the current user, as exposed via the JSF
+ * ExternalContext.
+ *
+ * @author Gavin King
+ */
+ at Scope(ScopeType.APPLICATION)
+ at BypassInterceptors
+ at Name("org.jboss.seam.web.isUserInRole")
+ at Install(precedence=FRAMEWORK, classDependencies="javax.faces.context.FacesContext")
+public class IsUserInRole extends org.jboss.seam.web.IsUserInRole
+{
+ @Override
+ protected Boolean isUserInRole(String role)
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ if ( facesContext != null )
+ {
+ return facesContext.getExternalContext().isUserInRole(role);
+ }
+
+ return super.isUserInRole(role);
+ }
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/Navigator.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/Navigator.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/Navigator.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,109 @@
+package org.jboss.seam.faces;
+
+import java.util.Map;
+
+import javax.faces.application.FacesMessage.Severity;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+import org.jboss.seam.navigation.Pages;
+import org.jboss.seam.util.Strings;
+
+public abstract class Navigator
+{
+ private static final LogProvider log = Logging.getLogProvider(Navigator.class);
+
+ /**
+ * Send an error.
+ */
+ protected void error(int code, String message)
+ {
+ if ( log.isDebugEnabled() ) log.debug("sending error: " + code);
+ org.jboss.seam.faces.HttpError httpError = org.jboss.seam.faces.HttpError.instance();
+ if (message==null)
+ {
+ httpError.send(code);
+ }
+ else
+ {
+ httpError.send(code, message);
+ }
+ }
+
+ protected void redirectExternal(String url) {
+ FacesManager.instance().redirectToExternalURL(url);
+ }
+
+ protected void redirect(String viewId, Map<String, Object> parameters)
+ {
+ redirect(viewId, parameters, true);
+ }
+
+ /**
+ * Redirect to the view id.
+ */
+ protected void redirect(String viewId, Map<String, Object> parameters, boolean includePageParams)
+ {
+ if ( Strings.isEmpty(viewId) )
+ {
+ viewId = Pages.getCurrentViewId();
+ }
+ if ( log.isDebugEnabled() ) log.debug("redirecting to: " + viewId);
+ FacesManager.instance().redirect(viewId, parameters, true, includePageParams);
+ }
+
+ /**
+ * Render the view id.
+ */
+ protected void render(String viewId)
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ if ( !Strings.isEmpty(viewId) )
+ {
+ UIViewRoot viewRoot = facesContext.getApplication().getViewHandler()
+ .createView(facesContext, viewId);
+ facesContext.setViewRoot(viewRoot);
+ }
+ else
+ {
+ viewId = Pages.getViewId(facesContext); //just for the log message
+ }
+ if ( log.isDebugEnabled() ) log.debug("rendering: " + viewId);
+ facesContext.renderResponse();
+ }
+
+ protected static String getDisplayMessage(Exception e, String message)
+ {
+ if ( Strings.isEmpty(message) && e.getMessage()!=null )
+ {
+ return e.getMessage();
+ }
+ else
+ {
+ return message;
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ protected static void addFacesMessage(String message, Severity severity, String control, Object... params)
+ {
+ if ( Contexts.isConversationContextActive() )
+ {
+ if ( !Strings.isEmpty(message) )
+ {
+ if ( Strings.isEmpty(control) )
+ {
+ FacesMessages.instance().add(severity, message, params);
+ }
+ else
+ {
+ FacesMessages.instance().addToControl(control, severity, message, params);
+ }
+ }
+ }
+ }
+
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/Parameters.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/Parameters.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/Parameters.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,67 @@
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.annotations.Install.FRAMEWORK;
+
+import java.util.Map;
+
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+
+/**
+ * Access to request parameters in the JSF environment.
+ *
+ * @author Gavin King
+ *
+ */
+ at Name("org.jboss.seam.web.parameters")
+ at BypassInterceptors
+ at Scope(ScopeType.STATELESS)
+ at Install(precedence=FRAMEWORK, classDependencies="javax.faces.context.FacesContext")
+public class Parameters extends org.jboss.seam.web.Parameters
+{
+
+ @Override
+ protected Object convertRequestParameter(String requestParameter, Class type)
+ {
+ if ( String.class.equals(type) ) return requestParameter;
+
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ if (facesContext==null)
+ {
+ throw new IllegalStateException("No FacesContext associated with current thread, cannot convert request parameter type");
+ }
+ else
+ {
+ Converter converter = facesContext.getApplication().createConverter(type);
+ if (converter==null)
+ {
+ throw new IllegalArgumentException("no converter for type: " + type);
+ }
+ UIViewRoot viewRoot = facesContext.getViewRoot();
+ return converter.getAsObject(
+ facesContext,
+ viewRoot==null ? new UIViewRoot() : viewRoot, //have to pass something here, or get a totally useless NPE from JSF
+ requestParameter );
+ }
+ }
+
+ @Override
+ public Map<String, String[]> getRequestParameters()
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ if ( facesContext != null )
+ {
+ return facesContext.getExternalContext().getRequestParameterValuesMap();
+ }
+
+ return super.getRequestParameters();
+ }
+
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/Redirect.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/Redirect.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/Redirect.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,204 @@
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.PerNestedConversation;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.core.AbstractMutable;
+import org.jboss.seam.core.Conversation;
+import org.jboss.seam.navigation.Pages;
+
+/**
+ * Convenient API for performing browser redirects with
+ * parameters.
+ *
+ * @author Gavin King
+ */
+ at Name("org.jboss.seam.faces.redirect")
+ at BypassInterceptors
+ at Scope(ScopeType.CONVERSATION)
+ at Install(precedence=BUILT_IN, classDependencies="javax.faces.context.FacesContext")
+ at PerNestedConversation
+public class Redirect extends AbstractMutable implements Serializable
+{
+ private static final long serialVersionUID = 6947384474861235210L;
+ private String viewId;
+ private Map<String, Object> parameters = new HashMap<String, Object>();
+ private boolean conversationPropagationEnabled = true;
+ private boolean conversationBegun;
+
+ /**
+ * Get the JSF view id to redirect to
+ */
+ public String getViewId()
+ {
+ return viewId;
+ }
+
+ /**
+ * Set the JSF view id to redirect to
+ *
+ * @param viewId any JSF view id
+ */
+ public void setViewId(String viewId)
+ {
+ setDirty(this.viewId, viewId);
+ this.viewId = viewId;
+ }
+
+ /**
+ * Get all the request parameters that have been set
+ */
+ public Map<String, Object> getParameters()
+ {
+ return parameters;
+ }
+
+ /**
+ * Set a request parameter value (to set a multi-valued
+ * request parameter, pass an array or collection as
+ * the value)
+ */
+ public void setParameter(String name, Object value)
+ {
+ Object old = parameters.put(name, value);
+ setDirty(old, value);
+ }
+
+ /**
+ * Capture the view id and request parameters from the
+ * current request and squirrel them away so we can
+ * return here later in the conversation.
+ *
+ * @deprecated use captureCurrentView()
+ */
+ public void captureCurrentRequest()
+ {
+ parameters.clear();
+ FacesContext context = FacesContext.getCurrentInstance();
+ parameters.putAll( context.getExternalContext().getRequestParameterMap() );
+ viewId = Pages.getViewId(context);
+ setDirty();
+ }
+
+ /**
+ * Capture the view id, request parameters and page parameters (which take
+ * precedence) from the current request and squirrel them away so we can
+ * return here later in the conversation. If no conversation is active,
+ * begin a conversation. The conversation is terminated by {@link
+ * Redirect#returnToCapturedView()} if begun by this method.
+ *
+ * @see Redirect#returnToCapturedView()
+ */
+ public void captureCurrentView()
+ {
+ FacesContext context = FacesContext.getCurrentInstance();
+
+ // If this isn't a faces request then just return
+ if (context == null) return;
+
+ // first capture all request parameters
+ parameters.putAll( context.getExternalContext().getRequestParameterMap() );
+ // then preserve page parameters, overwriting request parameters with same names
+ parameters.putAll( Pages.instance().getStringValuesFromPageContext(context) );
+
+ // special case only needed for actionMethod if decide not to capture all request parameters
+ //if (context.getExternalContext().getRequestParameterMap().containsKey("actionMethod"))
+ //{
+ // parameters.put("actionMethod", context.getExternalContext().getRequestParameterMap().get("actionMethod"));
+ //}
+
+ viewId = Pages.getViewId(context);
+ conversationBegun = Conversation.instance().begin(true, false);
+ setDirty();
+ //if the request ends with an exception,
+ //the conversation context never gets
+ //flushed....
+ Contexts.getConversationContext().flush();
+ }
+
+ /**
+ * Should the conversation be propagated across the redirect?
+ * @return true by default
+ */
+ public boolean isConversationPropagationEnabled()
+ {
+ return conversationPropagationEnabled;
+ }
+
+ /**
+ * Note that conversations are propagated by default
+ */
+ public void setConversationPropagationEnabled(boolean conversationPropagationEnabled)
+ {
+ this.conversationPropagationEnabled = conversationPropagationEnabled;
+ }
+
+ /**
+ * Perform the redirect
+ */
+ public void execute()
+ {
+ FacesManager.instance().redirect(viewId, parameters, conversationPropagationEnabled, true);
+ }
+
+ /**
+ * Redirect to the captured view, and end any conversation
+ * that began in captureCurrentView().
+ *
+ *@see Redirect#captureCurrentView()
+ */
+ public boolean returnToCapturedView()
+ {
+ if (viewId!=null)
+ {
+ if (conversationBegun)
+ {
+ Conversation.instance().end();
+ }
+ execute();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ //TODO: replacement for Conversation.endAndRedirect()
+ /*public boolean returnToParentView()
+ {
+ Manager manager = Manager.instance();
+ String viewId = manager.getParentConversationViewId();
+ if (viewId==null)
+ {
+ return false;
+ }
+ else
+ {
+ manager.redirect(viewId);
+ return true;
+ }
+ }*/
+
+ public static Redirect instance()
+ {
+ if ( !Contexts.isConversationContextActive() )
+ {
+ throw new IllegalStateException("No active conversation context");
+ }
+ return (Redirect) Component.getInstance(Redirect.class, ScopeType.CONVERSATION);
+ }
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/RedirectException.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/RedirectException.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/RedirectException.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,17 @@
+package org.jboss.seam.faces;
+
+import java.io.IOException;
+
+public class RedirectException extends RuntimeException
+{
+
+ public RedirectException(IOException ioe)
+ {
+ super(ioe);
+ }
+
+ public RedirectException(String message)
+ {
+ super(message);
+ }
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/Renderer.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/Renderer.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/Renderer.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,23 @@
+package org.jboss.seam.faces;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+
+/**
+ * A component for direct rendering of
+ * templates. Especially useful with
+ * Seam Mail.
+ *
+ */
+ at Name("org.jboss.seam.faces.renderer")
+ at Install(false)
+public abstract class Renderer
+{
+ public abstract String render(String viewId);
+
+ public static Renderer instance()
+ {
+ return (Renderer) Component.getInstance(Renderer.class);
+ }
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/ResourceLoader.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/ResourceLoader.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/ResourceLoader.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,56 @@
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.annotations.Install.FRAMEWORK;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.util.FacesResources;
+
+/**
+ * Access to application resources in tye JSF environment.
+ *
+ * @author Gavin King
+ *
+ */
+ at Scope(ScopeType.STATELESS)
+ at BypassInterceptors
+ at Install(precedence=FRAMEWORK, classDependencies="javax.faces.context.FacesContext")
+ at Name("org.jboss.seam.core.resourceLoader")
+public class ResourceLoader extends org.jboss.seam.core.ResourceLoader
+{
+
+ @Override
+ public InputStream getResourceAsStream(String resource)
+ {
+ javax.faces.context.FacesContext context = javax.faces.context.FacesContext.getCurrentInstance();
+ if (context!=null)
+ {
+ return FacesResources.getResourceAsStream( resource, context.getExternalContext() );
+ }
+ else
+ {
+ return super.getResourceAsStream(resource);
+ }
+ }
+
+ @Override
+ public URL getResource(String resource)
+ {
+ javax.faces.context.FacesContext context = javax.faces.context.FacesContext.getCurrentInstance();
+ if (context!=null)
+ {
+ return FacesResources.getResource( resource, context.getExternalContext() );
+ }
+ else
+ {
+ return super.getResource(resource);
+ }
+ }
+
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/Selector.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/Selector.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/Selector.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,122 @@
+package org.jboss.seam.faces;
+
+import java.io.Serializable;
+
+import javax.faces.context.FacesContext;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jboss.seam.core.AbstractMutable;
+
+/**
+ * Support for selector objects which remember their selection as a cookie
+ *
+ * @author Gavin King
+ */
+public abstract class Selector extends AbstractMutable implements Serializable
+{
+ public static final int DEFAULT_MAX_AGE = 31536000; // 1 year in seconds
+ private boolean cookieEnabled;
+ private int cookieMaxAge = DEFAULT_MAX_AGE;
+ private String cookiePath= "/";
+
+ /**
+ * Is the cookie enabled?
+ * @return false by default
+ */
+ public boolean isCookieEnabled()
+ {
+ return cookieEnabled;
+ }
+ public void setCookieEnabled(boolean cookieEnabled)
+ {
+ setDirty(this.cookieEnabled, cookieEnabled);
+ this.cookieEnabled = cookieEnabled;
+ }
+ /**
+ * The max age of the cookie
+ * @return 1 year by default
+ */
+ public int getCookieMaxAge()
+ {
+ return cookieMaxAge;
+ }
+ public void setCookieMaxAge(int cookieMaxAge)
+ {
+ this.cookieMaxAge = cookieMaxAge;
+ }
+
+ public String getCookiePath()
+ {
+ return cookiePath;
+ }
+
+ public void setCookiePath(String cookiePath)
+ {
+ this.cookiePath = cookiePath;
+ }
+
+ /**
+ * Override to define the cookie name
+ */
+ protected abstract String getCookieName();
+
+ /**
+ * Get the value of the cookie
+ */
+ protected String getCookieValueIfEnabled()
+ {
+ return isCookieEnabled() ?
+ getCookieValue() : null;
+ }
+
+ protected Cookie getCookie()
+ {
+ FacesContext ctx = FacesContext.getCurrentInstance();
+ if (ctx != null)
+ {
+ return (Cookie) ctx.getExternalContext().getRequestCookieMap()
+ .get( getCookieName() );
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ protected String getCookieValue()
+ {
+ Cookie cookie = getCookie();
+ return cookie==null ? null : cookie.getValue();
+ }
+
+ protected void clearCookieValue()
+ {
+ Cookie cookie = getCookie();
+ if ( cookie!=null )
+ {
+ HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
+ cookie.setValue(null);
+ cookie.setPath(cookiePath);
+ cookie.setMaxAge(0);
+ response.addCookie(cookie);
+ }
+ }
+
+ /**
+ * Set the cookie
+ */
+ protected void setCookieValueIfEnabled(String value)
+ {
+ FacesContext ctx = FacesContext.getCurrentInstance();
+
+ if ( isCookieEnabled() && ctx != null)
+ {
+ HttpServletResponse response = (HttpServletResponse) ctx.getExternalContext().getResponse();
+ Cookie cookie = new Cookie( getCookieName(), value );
+ cookie.setMaxAge( getCookieMaxAge() );
+ cookie.setPath(cookiePath);
+ response.addCookie(cookie);
+ }
+ }
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/Switcher.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/Switcher.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/Switcher.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,125 @@
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.faces.model.SelectItem;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.core.ConversationEntries;
+import org.jboss.seam.core.ConversationEntry;
+import org.jboss.seam.core.Manager;
+import org.jboss.seam.web.Session;
+
+/**
+ * Support for the conversation switcher drop-down menu.
+ *
+ * @author Gavin King
+ */
+ at Scope(ScopeType.PAGE)
+ at Name("org.jboss.seam.faces.switcher")
+ at Install(precedence=BUILT_IN, classDependencies="javax.faces.context.FacesContext")
+ at BypassInterceptors
+public class Switcher implements Serializable
+{
+
+ private static final long serialVersionUID = -6403911073853051938L;
+ private List<SelectItem> selectItems;
+ private String conversationIdOrOutcome;
+ private String resultingConversationIdOrOutcome;
+
+ @Create
+ public void createSelectItems()
+ {
+ ConversationEntries conversationEntries = ConversationEntries.getInstance();
+ if (conversationEntries==null)
+ {
+ selectItems = Collections.EMPTY_LIST;
+ }
+ else
+ {
+ Set<ConversationEntry> orderedEntries = new TreeSet<ConversationEntry>();
+ orderedEntries.addAll( conversationEntries.getConversationEntries() );
+ selectItems = new ArrayList<SelectItem>( conversationEntries.size() );
+ for ( ConversationEntry entry: orderedEntries )
+ {
+ if ( entry.isDisplayable() && !Session.instance().isInvalid() )
+ {
+ selectItems.add( new SelectItem( entry.getId(), entry.getDescription() ) );
+ }
+ }
+ }
+ }
+
+ public List<SelectItem> getSelectItems()
+ {
+ return selectItems;
+ }
+
+ private String getLongRunningConversationId()
+ {
+ Manager manager = Manager.instance();
+ if ( manager.isLongRunningConversation() )
+ {
+ return manager.getCurrentConversationId();
+ }
+ else if ( manager.isNestedConversation() )
+ {
+ return manager.getParentConversationId();
+ }
+ else
+ {
+ //TODO: is there any way to set it to the current outcome, instead of null?
+ return null;
+ }
+ }
+
+ public String getConversationIdOrOutcome()
+ {
+ return resultingConversationIdOrOutcome==null ?
+ getLongRunningConversationId() :
+ resultingConversationIdOrOutcome;
+ }
+
+ public void setConversationIdOrOutcome(String selectedId)
+ {
+ this.conversationIdOrOutcome = selectedId;
+ }
+
+ public String select()
+ {
+
+ boolean isOutcome = conversationIdOrOutcome==null ||
+ (!Character.isDigit(conversationIdOrOutcome.charAt(0)) && conversationIdOrOutcome.indexOf(':') < 0);
+
+ String actualOutcome;
+ if (isOutcome)
+ {
+ resultingConversationIdOrOutcome = conversationIdOrOutcome;
+ actualOutcome = conversationIdOrOutcome;
+ }
+ else
+ {
+ ConversationEntry ce = ConversationEntries.instance().getConversationEntry(conversationIdOrOutcome);
+ if (ce!=null)
+ {
+ resultingConversationIdOrOutcome = ce.getId();
+ ce.redirect();
+ }
+ actualOutcome = null;
+ }
+ return actualOutcome;
+ }
+
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/UiComponent.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/UiComponent.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/UiComponent.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,81 @@
+package org.jboss.seam.faces;
+
+import static org.jboss.seam.ScopeType.STATELESS;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.util.AbstractMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Unwrap;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+
+/**
+ * Access to UIComponents in the current view, by id.
+ *
+ * @author Gavin King
+ *
+ */
+ at Name("org.jboss.seam.faces.uiComponent")
+ at BypassInterceptors
+ at Scope(STATELESS)
+ at Install(precedence=BUILT_IN, classDependencies="javax.faces.context.FacesContext")
+public class UiComponent
+{
+
+ @Unwrap
+ public Map<String, UIComponent> getViewComponents()
+ {
+ return new AbstractMap<String, UIComponent>()
+ {
+
+ @Override
+ public boolean containsKey(Object key) {
+ return get(key) != null;
+ }
+
+
+ @Override
+ public Set<Map.Entry<String, UIComponent>> entrySet()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public UIComponent get(Object key)
+ {
+ if ( !(key instanceof String) ) return null;
+ try
+ {
+ FacesContext context = FacesContext.getCurrentInstance();
+
+ if (context == null) {
+ return null;
+ }
+
+ UIViewRoot viewRoot = context.getViewRoot();
+
+ if (viewRoot == null)
+ {
+ return null;
+ }
+
+ return viewRoot.findComponent( (String) key );
+ }
+ catch (IllegalArgumentException iae)
+ {
+ return null;
+ }
+ }
+
+ };
+ }
+
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/UserPrincipal.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/UserPrincipal.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/UserPrincipal.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,30 @@
+package org.jboss.seam.faces;
+
+import java.security.Principal;
+
+import javax.annotation.Named;
+import javax.context.ApplicationScoped;
+import javax.faces.context.FacesContext;
+
+/**
+ * Manager component for the current user Principal
+ * exposed via the JSF ExternalContext.
+ *
+ * @author Gavin King
+ */
+ at Named
+ at ApplicationScoped
+public class UserPrincipal extends org.jboss.seam.web.UserPrincipal
+{
+ @Unwrap @Override
+ public Principal getUserPrincipal()
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ if ( facesContext != null )
+ {
+ return facesContext.getExternalContext().getUserPrincipal();
+ }
+
+ return super.getUserPrincipal();
+ }
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/Validation.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/Validation.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/Validation.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,51 @@
+package org.jboss.seam.faces;
+
+import javax.annotation.Named;
+import javax.faces.context.FacesContext;
+import javax.inject.Current;
+import javax.inject.manager.Manager;
+
+import org.jboss.seam.faces.events.ValidationFailedEvent;
+
+/**
+ * Allows the application to determine whether the JSF validation
+ * phase completed successfully, or if a validation failure
+ * occurred.
+ *
+ * @author Gavin king
+ *
+ */
+ at Named
+public class Validation
+{
+ private boolean succeeded;
+ private boolean failed;
+
+ @Current Manager manager;
+
+ public void afterProcessValidations(FacesContext facesContext)
+ {
+ failed = facesContext.getRenderResponse();
+ if (failed)
+ {
+ manager.fireEvent(new ValidationFailedEvent());
+ }
+ succeeded = !failed;
+ }
+
+ public boolean isSucceeded()
+ {
+ return succeeded;
+ }
+
+ public boolean isFailed()
+ {
+ return failed;
+ }
+
+ public void fail()
+ {
+ failed = true;
+ succeeded = false;
+ }
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/events/ValidationFailedEvent.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/events/ValidationFailedEvent.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/events/ValidationFailedEvent.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,11 @@
+package org.jboss.seam.faces.events;
+
+/**
+ * This event is raised when JSF validation fails.
+ *
+ * @author Shane Bryzak
+ */
+public class ValidationFailedEvent
+{
+
+}
Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/package-info.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/package-info.java (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/package-info.java 2009-04-23 01:09:20 UTC (rev 10601)
@@ -0,0 +1,11 @@
+/**
+ * A set of Seam components for working with JSF.
+ * Some of these components extend core components
+ * and add JSF-specific functionality. Others
+ * exist to put a friendly face to JSF.
+ */
+ at AutoCreate
+package org.jboss.seam.faces;
+
+import org.jboss.seam.annotations.AutoCreate;
+
More information about the seam-commits
mailing list