[seam-commits] Seam SVN: r11026 - in modules/trunk: el/src/test/java/org/jboss/seam/el and 19 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Thu May 28 15:13:07 EDT 2009


Author: dan.j.allen
Date: 2009-05-28 15:13:06 -0400 (Thu, 28 May 2009)
New Revision: 11026

Added:
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/context/
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/context/FacesContextProducer.java
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/el/FacesExpressions.java
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/international/
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/international/FacesLocaleResolver.java
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/international/FacesMessages.java
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/resources/
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/resources/FacesResourceLoader.java
   modules/trunk/faces/src/test/java/org/jboss/seam/faces/context/
   modules/trunk/faces/src/test/java/org/jboss/seam/faces/context/FacesContextProducerTest.java
   modules/trunk/faces/src/test/java/org/jboss/seam/faces/el/
   modules/trunk/faces/src/test/java/org/jboss/seam/faces/el/FacesExpressionsTest.java
   modules/trunk/faces/src/test/java/org/jboss/seam/faces/international/
   modules/trunk/faces/src/test/java/org/jboss/seam/faces/international/FacesLocaleProducerTest.java
   modules/trunk/faces/src/test/java/org/jboss/seam/faces/international/FacesMessagesTest.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/AutoInterpolatedMessages.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/AutoInterpolatedMessagesProducer.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/InterpolatingResourceBundle.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleResolver.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleResolverProducer.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/SeamResourceBundleAdapter.java
   modules/trunk/international/src/test/java/org/jboss/seam/international/AutoInterpolatedMessagesTest.java
   modules/trunk/international/src/test/java/org/jboss/seam/international/Thing.java
   modules/trunk/international/src/test/resources/messages.properties
Removed:
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesContextProducer.java
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesExpressions.java
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesMessages.java
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesResourceLoader.java
   modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesContextProducerTest.java
   modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesExpressionsTest.java
   modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesMessagesTest.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/ResourceBundle.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/ResourceLoader.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/util/Resources.java
Modified:
   modules/trunk/el/src/main/java/org/jboss/seam/el/AbstractELResolver.java
   modules/trunk/el/src/main/java/org/jboss/seam/el/ExpressionsProducer.java
   modules/trunk/el/src/test/java/org/jboss/seam/el/ExpressionsProducerTest.java
   modules/trunk/faces/pom.xml
   modules/trunk/faces/src/main/java/org/jboss/seam/faces/DataModels.java
   modules/trunk/faces/src/main/resources/META-INF/seam-faces.taglib.xml
   modules/trunk/faces/src/test/resources/test-suite.xml
   modules/trunk/international/pom.xml
   modules/trunk/international/src/main/java/org/jboss/seam/international/Interpolator.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleProducer.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/MessagesProducer.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/StatusMessage.java
   modules/trunk/international/src/main/java/org/jboss/seam/international/StatusMessages.java
   modules/trunk/international/src/test/java/org/jboss/seam/international/InterpolatorTest.java
   modules/trunk/international/src/test/java/org/jboss/seam/international/LocaleProducerTest.java
   modules/trunk/international/src/test/java/org/jboss/seam/international/StatusMessagesTest.java
   modules/trunk/parent/pom.xml
   modules/trunk/resources/src/main/java/org/jboss/seam/resources/DefaultResourceLoader.java
   modules/trunk/resources/src/main/java/org/jboss/seam/resources/ResourceLoader.java
   modules/trunk/resources/src/main/java/org/jboss/seam/resources/ResourceLoaderProducer.java
Log:
add resource module to parent
add methods to ResourceLoader
implement runtime selected ResourceLoader w/ JSF impl
implement Seam resource bundle
add resource bundle functionality to StatusMessages
implement runtime selected Locale w/ JSF impl
repackaging in faces module
implements runtime selected Expressions w/ JSF impl


Modified: modules/trunk/el/src/main/java/org/jboss/seam/el/AbstractELResolver.java
===================================================================
--- modules/trunk/el/src/main/java/org/jboss/seam/el/AbstractELResolver.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/el/src/main/java/org/jboss/seam/el/AbstractELResolver.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,4 +1,4 @@
-/* 
+/*
  * JBoss, Home of Professional Open Source
  * Copyright 2009, Red Hat Middleware LLC, and individual contributors
  * by the @authors tag. See the copyright.txt in the distribution for a
@@ -24,6 +24,7 @@
 package org.jboss.seam.el;
 
 import java.util.Iterator;
+
 import javax.el.ELContext;
 import javax.el.ELResolver;
 
@@ -38,8 +39,8 @@
  *
  * @author Dan Allen
  */
-public abstract class AbstractELResolver extends ELResolver {
-
+public abstract class AbstractELResolver extends ELResolver
+{
    /**
     * A default implementation that returns <code>null</code> unconditionally.
     *
@@ -93,5 +94,4 @@
    public void setValue(ELContext context, Object base, Object property, Object value)
    {
    }
-
 }

Modified: modules/trunk/el/src/main/java/org/jboss/seam/el/ExpressionsProducer.java
===================================================================
--- modules/trunk/el/src/main/java/org/jboss/seam/el/ExpressionsProducer.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/el/src/main/java/org/jboss/seam/el/ExpressionsProducer.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,6 +1,7 @@
 package org.jboss.seam.el;
 
 import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.RequestScoped;
 import javax.enterprise.inject.Initializer;
 import javax.enterprise.inject.Produces;
 import javax.enterprise.inject.spi.BeanManager;
@@ -26,6 +27,7 @@
 
    @Override
    public
+   @RequestScoped
    @Produces
    Expressions selectImplementation()
    {

Modified: modules/trunk/el/src/test/java/org/jboss/seam/el/ExpressionsProducerTest.java
===================================================================
--- modules/trunk/el/src/test/java/org/jboss/seam/el/ExpressionsProducerTest.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/el/src/test/java/org/jboss/seam/el/ExpressionsProducerTest.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -15,6 +15,6 @@
    {
       Expressions expressions = getCurrentManager().getInstanceByType(Expressions.class);
       assertNotNull(expressions);
-      assertSame(expressions.getClass(), Expressions.class);
+      assertSame(expressions.getExpressionFactory(), SeamExpressionFactory.INSTANCE);
    }
 }

Modified: modules/trunk/faces/pom.xml
===================================================================
--- modules/trunk/faces/pom.xml	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/faces/pom.xml	2009-05-28 19:13:06 UTC (rev 11026)
@@ -60,6 +60,11 @@
          <artifactId>seam-international</artifactId>
       </dependency>
 
+      <dependency>
+         <groupId>${seam.groupId}</groupId>
+         <artifactId>seam-resources</artifactId> <!-- may become inherited -->
+      </dependency>
+
       <!-- QUESTION do we want this dependency? -->
       <dependency>
          <groupId>${seam.groupId}</groupId>

Modified: modules/trunk/faces/src/main/java/org/jboss/seam/faces/DataModels.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/DataModels.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/DataModels.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -5,6 +5,7 @@
 import java.util.Set;
 
 import javax.faces.model.DataModel;
+
 import org.jboss.seam.faces.model.ArrayDataModel;
 import org.jboss.seam.faces.model.ListDataModel;
 import org.jboss.seam.faces.model.MapDataModel;

Deleted: modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesContextProducer.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesContextProducer.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesContextProducer.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,20 +0,0 @@
-//$Id: FacesContext.java 5350 2007-06-20 17:53:19Z gavin $
-package org.jboss.seam.faces;
-
-import javax.enterprise.inject.Produces;
-import javax.faces.context.FacesContext;
-
-/**
- * Support for injecting the JSF FacesContext object
- * 
- * @author Gavin King
- */
-public class FacesContextProducer
-{
-   public
-   @Produces
-   FacesContext getFacesContext()
-   {
-      return FacesContext.getCurrentInstance();
-   }
-}

Deleted: modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesExpressions.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesExpressions.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesExpressions.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,35 +0,0 @@
-//$Id: FacesExpressions.java 9684 2008-12-01 21:41:20Z dan.j.allen $
-package org.jboss.seam.faces;
-
-import javax.el.ELContext;
-import javax.faces.context.FacesContext;
-
-import org.jboss.seam.beans.RuntimeSelected;
-import org.jboss.seam.beans.RuntimeSelectedBean;
-import org.jboss.seam.el.Expressions;
-
-/**
- * Factory for method and value bindings in a JSF environment.
- * 
- * @author Gavin King
- * @author Dan Allen
- */
-public
- at RuntimeSelected
-class FacesExpressions extends Expressions implements RuntimeSelectedBean
-{
-   public boolean isActive()
-   {
-      return FacesContext.getCurrentInstance() != null && FacesContext.getCurrentInstance().getCurrentPhaseId() != null;
-   }
-
-   /**
-    * @return the JSF ELContext
-    */
-   @Override
-   public ELContext getELContext()
-   {
-      return FacesContext.getCurrentInstance().getELContext();
-   }
-
-}
\ No newline at end of file

Deleted: modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesMessages.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesMessages.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesMessages.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,238 +0,0 @@
-package org.jboss.seam.faces;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.enterprise.inject.Initializer;
-import javax.faces.application.FacesMessage;
-import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-
-import org.jboss.seam.international.StatusMessage;
-import org.jboss.seam.international.StatusMessages;
-import org.jboss.seam.international.StatusMessagesDelegate;
-import org.jboss.webbeans.log.LogProvider;
-import org.jboss.webbeans.log.Logging;
-
-/**
- * <p>
- * A bean which wraps the generic StatusMessages component to provide support
- * for JSF. The StatusMessage objects are translated to JSF FacesMessage objects
- * and registered with the FacesContext by this class prior to view rendering or
- * a servlet redirect.
- * </p>
- * 
- * <p>
- * To access the JSF FacesMessage objects once they have been registered with
- * the FacesContext, you should use the methods getMessageList() and
- * getMessagesList(String), which were added to FacesContext in JSF 2.0.
- * </p>
- * 
- * <p>
- * For instance, to retrieve the list of global messages, you can use the
- * following value expression in your page:
- * </p>
- * 
- * <pre>
- * #{facesContext.getMessageList(null)}
- * </pre>
- * 
- * <p>
- * To retrieve the list of messages for a "client id", you can use this
- * expression:
- * </p>
- * 
- * <pre>
- * #{facesContext.getMessageList('username')}
- * </pre>
- * 
- * <p>
- * These examples rely, of course, on the JBoss EL.
- * </p>
- * 
- * @author Gavin King
- * @author Pete Muir
- * @author Dan Allen
- */
-public
- at Faces
-class FacesMessages extends StatusMessagesDelegate
-{
-   private static final LogProvider log = Logging.getLogProvider(FacesMessages.class);
-   
-   private StatusMessages statusMessages;
-
-   public
-   @Initializer
-   FacesMessages(StatusMessages statusMessages)
-   {
-      this.statusMessages = statusMessages;
-   }
-
-   @Override
-   public StatusMessages getStatusMessages()
-   {
-      return this.statusMessages;
-   }
-
-   /**
-    * A convenience method to convert a FacesMessage into a StatusMessage and
-    * register it as a global message. It may be that the application receives a
-    * FacesMessage object from some part of the system and needs to join it with
-    * the current set of StatusMessage objects.
-    * 
-    * @param message A populated JSF FacesMessage object
-    */
-   public void add(FacesMessage message)
-   {
-      add(toSeverity(message.getSeverity()), null, null, message.getSummary(), message.getDetail());
-   }
-
-   /**
-    * A convenience method to convert a FacesMessage into a StatusMessage and
-    * register it with a control. It may be that the application receives a
-    * FacesMessage object from some part of the system and needs to join it with
-    * the current set of StatusMessage objects.
-    * 
-    * @param id The client id of the target component
-    * @param message A populated JSF FacesMessage object
-    */
-   public void addToControl(String id, FacesMessage message)
-   {
-      addToControl(id, toSeverity(message.getSeverity()), null, null, message.getSummary(), message.getDetail());
-   }
-   
-   /**
-    * Called by a JSF SystemEventListener listening for the PreRenderViewEvent
-    * to transpose Seam status messages to real JSF messages and register them
-    * with the FacesContext.
-    */
-   @Override
-   public void onBeforeRender()
-   {
-      super.onBeforeRender();
-      FacesContext facesContext = FacesContext.getCurrentInstance();
-      for (StatusMessage statusMessage : getGlobalMessages())
-      {
-         facesContext.addMessage(null, toFacesMessage(statusMessage));
-      }
-      for (Map.Entry<String, List<StatusMessage>> messagesForKey : getKeyedMessages().entrySet())
-      {
-         String clientId = getClientId(messagesForKey.getKey(), facesContext);
-         if (clientId == null)
-         {
-            log.warn("Could not locate control '" + messagesForKey.getKey() + "' when registering JSF message. A global message will be created as a fallback.");
-         }
-         for (StatusMessage statusMessage : messagesForKey.getValue())
-         {
-            facesContext.addMessage(clientId, toFacesMessage(statusMessage));
-         }
-      }
-      clear();
-   }
-
-   /**
-    * Convert a StatusMessage to a FacesMessage
-    */
-   private FacesMessage toFacesMessage(StatusMessage statusMessage)
-   {
-      if (statusMessage.getSummary() != null && statusMessage.getSummary().length() > 0)
-      {
-         return new FacesMessage(toFacesSeverity(statusMessage.getSeverity()), statusMessage.getSummary(), statusMessage.getDetail());
-      }
-      else
-      {
-         return null;
-      }
-   }
-
-   /**
-    * Convert a FacesMessage.Severity to a StatusMessage.Severity
-    */
-   private static StatusMessage.Severity toSeverity(FacesMessage.Severity severity)
-   {
-      if (FacesMessage.SEVERITY_ERROR.equals(severity))
-      {
-         return StatusMessage.Severity.ERROR;
-      }
-      else if (FacesMessage.SEVERITY_FATAL.equals(severity))
-      {
-         return StatusMessage.Severity.FATAL;
-      }
-      else if (FacesMessage.SEVERITY_WARN.equals(severity))
-      {
-         return StatusMessage.Severity.WARN;
-      }
-      else
-      {
-         return StatusMessage.Severity.INFO;
-      }
-   }
-   
-   /**
-    * Convert a StatusMessage.Severity to a FacesMessage.Severity
-    */
-   private FacesMessage.Severity toFacesSeverity(StatusMessage.Severity severity)
-   {
-      switch (severity)
-      {
-         case ERROR:
-            return FacesMessage.SEVERITY_ERROR;
-         case FATAL:
-            return FacesMessage.SEVERITY_FATAL;
-         case WARN:
-            return FacesMessage.SEVERITY_WARN;
-         case INFO:
-         default:
-            return FacesMessage.SEVERITY_INFO;
-      }
-   }
-
-   /**
-    * Calculate the JSF client ID from the provided widget ID.
-    * TODO It would be great if this could do suffix maching.
-    */
-   private String getClientId(String targetId, FacesContext facesContext)
-   {
-      if (isAbsoluteClientIdPresent(targetId, facesContext))
-      {
-         return targetId;
-      }
-      else
-      {
-         return getClientId(facesContext.getViewRoot(), targetId, facesContext);
-      }
-   }
-
-   /**
-    * FIXME does not work if element is inside of form with prependId="false"
-    */
-   private boolean isAbsoluteClientIdPresent(String targetId, FacesContext facesContext)
-   {
-      return facesContext.getViewRoot().findComponent(targetId) != null;
-   }
-
-   private String getClientId(UIComponent component, String targetLocalId, FacesContext facesContext)
-   {
-      String currentLocalId = component.getId();
-      if (currentLocalId != null && currentLocalId.equals(targetLocalId))
-      {
-         return component.getClientId(facesContext);
-      }
-      else
-      {
-         Iterator<UIComponent> iter = component.getFacetsAndChildren();
-         while (iter.hasNext())
-         {
-            String clientId = getClientId(iter.next(), targetLocalId, facesContext);
-            if (clientId != null)
-            {
-               return clientId;
-            }
-         }
-         return null;
-      }
-   }
-   
-}

Deleted: modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesResourceLoader.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesResourceLoader.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesResourceLoader.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,72 +0,0 @@
-package org.jboss.seam.faces;
-
-import java.io.InputStream;
-import java.net.URL;
-
-import javax.faces.context.FacesContext;
-import javax.servlet.ServletContext;
-
-import org.jboss.seam.international.ResourceLoader;
-import org.jboss.webbeans.log.LogProvider;
-import org.jboss.webbeans.log.Logging;
-
-/**
- * Extend the standard {@link ResourceLoader} and attempt to first load
- * the resource from the web context root.
- *
- * @author Dan Allen
- */
-public class FacesResourceLoader extends ResourceLoader
-{
-   private static final LogProvider log = Logging.getLogProvider(FacesResourceLoader.class);
-   
-   //@Current
-   FacesContext facesContext;
-
-   @Override
-   protected URL getResource(String path, String relativePath)
-   {
-      ServletContext servletContext = getServletContext();
-      if (servletContext != null)
-      {
-         try
-         {
-            URL url = servletContext.getResource(path);
-            log.debug("Loaded resource from servlet context: " + url);
-            return url;
-         }
-         catch (Exception e)
-         {
-            // swallow
-         }
-      }
-
-      return super.getResource(path, relativePath);
-   }
-
-   @Override
-   protected InputStream getResourceAsStream(String path, String relativePath)
-   {
-      ServletContext servletContext = getServletContext();
-      if (servletContext != null)
-      {
-         try
-         {
-            InputStream stream = servletContext.getResourceAsStream(path);
-            log.debug("Loaded resource stream from servlet context: " + path);
-            return stream;
-         }
-         catch (Exception e)
-         {
-            // swallow
-         }
-      }
-
-      return super.getResourceAsStream(path, relativePath);
-   }
-
-   private ServletContext getServletContext()
-   {
-      return (ServletContext) facesContext.getExternalContext().getContext();
-   }
-}

Copied: modules/trunk/faces/src/main/java/org/jboss/seam/faces/context/FacesContextProducer.java (from rev 10994, modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesContextProducer.java)
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/context/FacesContextProducer.java	                        (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/context/FacesContextProducer.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,22 @@
+//$Id: FacesContext.java 5350 2007-06-20 17:53:19Z gavin $
+package org.jboss.seam.faces.context;
+
+import javax.enterprise.inject.Produces;
+import javax.faces.context.FacesContext;
+
+/**
+ * Support for injecting the JSF FacesContext object
+ * 
+ * QUESTION should we return null if there is no current phase id? (seems to be a common check)
+ * 
+ * @author Gavin King
+ */
+public class FacesContextProducer
+{
+   public
+   @Produces
+   FacesContext getFacesContext()
+   {
+      return FacesContext.getCurrentInstance();
+   }
+}

Copied: modules/trunk/faces/src/main/java/org/jboss/seam/faces/el/FacesExpressions.java (from rev 11012, modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesExpressions.java)
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/el/FacesExpressions.java	                        (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/el/FacesExpressions.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,40 @@
+//$Id: FacesExpressions.java 9684 2008-12-01 21:41:20Z dan.j.allen $
+package org.jboss.seam.faces.el;
+
+import javax.el.ELContext;
+import javax.enterprise.inject.Current;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.beans.RuntimeSelected;
+import org.jboss.seam.beans.RuntimeSelectedBean;
+import org.jboss.seam.el.Expressions;
+
+/**
+ * Factory for method and value bindings in a JSF environment.
+ * 
+ * @author Gavin King
+ * @author Dan Allen
+ */
+public
+ at RuntimeSelected
+class FacesExpressions extends Expressions implements RuntimeSelectedBean
+{
+   @Current FacesContext facesContext;
+   
+   public boolean isActive()
+   {
+      // FIXME temporary hack since a bogus FacesContext is being injected
+      facesContext = FacesContext.getCurrentInstance();
+      return facesContext != null && facesContext.getCurrentPhaseId() != null;
+   }
+
+   /**
+    * @return the JSF ELContext
+    */
+   @Override
+   public ELContext getELContext()
+   {
+      return facesContext.getELContext();
+   }
+
+}
\ No newline at end of file

Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/international/FacesLocaleResolver.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/international/FacesLocaleResolver.java	                        (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/international/FacesLocaleResolver.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,45 @@
+package org.jboss.seam.faces.international;
+
+import java.util.Locale;
+
+import javax.enterprise.inject.Current;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.beans.RuntimeSelected;
+import org.jboss.seam.beans.RuntimeSelectedBean;
+import org.jboss.seam.international.LocaleResolver;
+
+/**
+ * A specialized version of the LocaleProducer that returns
+ * the Locale associated with the current UIViewRoot or,
+ * if the UIViewRoot has not been established, uses the
+ * ViewHandler to calculate the Locale.
+ * 
+ * @author Dan Allen
+ */
+public
+ at RuntimeSelected
+class FacesLocaleResolver extends LocaleResolver implements RuntimeSelectedBean
+{
+   @Current FacesContext facesContext;
+   
+   public boolean isActive()
+   {
+      // FIXME temporary hack since the FacesContext being injected is bogus
+      facesContext = FacesContext.getCurrentInstance();
+      return facesContext != null && facesContext.getCurrentPhaseId() != null;
+   }
+   
+   @Override
+   public Locale getLocale()
+   {
+      if (facesContext.getViewRoot() != null)
+      {
+         return facesContext.getViewRoot().getLocale();
+      }
+      else
+      {
+         return facesContext.getApplication().getViewHandler().calculateLocale(facesContext);
+      }
+   }
+}

Copied: modules/trunk/faces/src/main/java/org/jboss/seam/faces/international/FacesMessages.java (from rev 11013, modules/trunk/faces/src/main/java/org/jboss/seam/faces/FacesMessages.java)
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/international/FacesMessages.java	                        (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/international/FacesMessages.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,239 @@
+package org.jboss.seam.faces.international;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.enterprise.inject.Initializer;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.faces.Faces;
+import org.jboss.seam.international.StatusMessage;
+import org.jboss.seam.international.StatusMessages;
+import org.jboss.seam.international.StatusMessagesDelegate;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+
+/**
+ * <p>
+ * A bean which wraps the generic StatusMessages component to provide support
+ * for JSF. The StatusMessage objects are translated to JSF FacesMessage objects
+ * and registered with the FacesContext by this class prior to view rendering or
+ * a servlet redirect.
+ * </p>
+ * 
+ * <p>
+ * To access the JSF FacesMessage objects once they have been registered with
+ * the FacesContext, you should use the methods getMessageList() and
+ * getMessagesList(String), which were added to FacesContext in JSF 2.0.
+ * </p>
+ * 
+ * <p>
+ * For instance, to retrieve the list of global messages, you can use the
+ * following value expression in your page:
+ * </p>
+ * 
+ * <pre>
+ * #{facesContext.getMessageList(null)}
+ * </pre>
+ * 
+ * <p>
+ * To retrieve the list of messages for a "client id", you can use this
+ * expression:
+ * </p>
+ * 
+ * <pre>
+ * #{facesContext.getMessageList('username')}
+ * </pre>
+ * 
+ * <p>
+ * These examples rely, of course, on the JBoss EL.
+ * </p>
+ * 
+ * @author Gavin King
+ * @author Pete Muir
+ * @author Dan Allen
+ */
+public
+ at Faces
+class FacesMessages extends StatusMessagesDelegate
+{
+   private static final LogProvider log = Logging.getLogProvider(FacesMessages.class);
+   
+   private StatusMessages statusMessages;
+
+   public
+   @Initializer
+   FacesMessages(StatusMessages statusMessages)
+   {
+      this.statusMessages = statusMessages;
+   }
+
+   @Override
+   public StatusMessages getStatusMessages()
+   {
+      return this.statusMessages;
+   }
+
+   /**
+    * A convenience method to convert a FacesMessage into a StatusMessage and
+    * register it as a global message. It may be that the application receives a
+    * FacesMessage object from some part of the system and needs to join it with
+    * the current set of StatusMessage objects.
+    * 
+    * @param message A populated JSF FacesMessage object
+    */
+   public void add(FacesMessage message)
+   {
+      add(toSeverity(message.getSeverity()), null, null, message.getSummary(), message.getDetail());
+   }
+
+   /**
+    * A convenience method to convert a FacesMessage into a StatusMessage and
+    * register it with a control. It may be that the application receives a
+    * FacesMessage object from some part of the system and needs to join it with
+    * the current set of StatusMessage objects.
+    * 
+    * @param id The client id of the target component
+    * @param message A populated JSF FacesMessage object
+    */
+   public void addToControl(String id, FacesMessage message)
+   {
+      addToControl(id, toSeverity(message.getSeverity()), null, null, message.getSummary(), message.getDetail());
+   }
+   
+   /**
+    * Called by a JSF SystemEventListener listening for the PreRenderViewEvent
+    * to transpose Seam status messages to real JSF messages and register them
+    * with the FacesContext.
+    */
+   @Override
+   public void onBeforeRender()
+   {
+      super.onBeforeRender();
+      FacesContext facesContext = FacesContext.getCurrentInstance();
+      for (StatusMessage statusMessage : getGlobalMessages())
+      {
+         facesContext.addMessage(null, toFacesMessage(statusMessage));
+      }
+      for (Map.Entry<String, List<StatusMessage>> messagesForKey : getKeyedMessages().entrySet())
+      {
+         String clientId = getClientId(messagesForKey.getKey(), facesContext);
+         if (clientId == null)
+         {
+            log.warn("Could not locate control '" + messagesForKey.getKey() + "' when registering JSF message. A global message will be created as a fallback.");
+         }
+         for (StatusMessage statusMessage : messagesForKey.getValue())
+         {
+            facesContext.addMessage(clientId, toFacesMessage(statusMessage));
+         }
+      }
+      clear();
+   }
+
+   /**
+    * Convert a StatusMessage to a FacesMessage
+    */
+   private FacesMessage toFacesMessage(StatusMessage statusMessage)
+   {
+      if (statusMessage.getSummary() != null && statusMessage.getSummary().length() > 0)
+      {
+         return new FacesMessage(toFacesSeverity(statusMessage.getSeverity()), statusMessage.getSummary(), statusMessage.getDetail());
+      }
+      else
+      {
+         return null;
+      }
+   }
+
+   /**
+    * Convert a FacesMessage.Severity to a StatusMessage.Severity
+    */
+   private static StatusMessage.Severity toSeverity(FacesMessage.Severity severity)
+   {
+      if (FacesMessage.SEVERITY_ERROR.equals(severity))
+      {
+         return StatusMessage.Severity.ERROR;
+      }
+      else if (FacesMessage.SEVERITY_FATAL.equals(severity))
+      {
+         return StatusMessage.Severity.FATAL;
+      }
+      else if (FacesMessage.SEVERITY_WARN.equals(severity))
+      {
+         return StatusMessage.Severity.WARN;
+      }
+      else
+      {
+         return StatusMessage.Severity.INFO;
+      }
+   }
+   
+   /**
+    * Convert a StatusMessage.Severity to a FacesMessage.Severity
+    */
+   private FacesMessage.Severity toFacesSeverity(StatusMessage.Severity severity)
+   {
+      switch (severity)
+      {
+         case ERROR:
+            return FacesMessage.SEVERITY_ERROR;
+         case FATAL:
+            return FacesMessage.SEVERITY_FATAL;
+         case WARN:
+            return FacesMessage.SEVERITY_WARN;
+         case INFO:
+         default:
+            return FacesMessage.SEVERITY_INFO;
+      }
+   }
+
+   /**
+    * Calculate the JSF client ID from the provided widget ID.
+    * TODO It would be great if this could do suffix maching.
+    */
+   private String getClientId(String targetId, FacesContext facesContext)
+   {
+      if (isAbsoluteClientIdPresent(targetId, facesContext))
+      {
+         return targetId;
+      }
+      else
+      {
+         return getClientId(facesContext.getViewRoot(), targetId, facesContext);
+      }
+   }
+
+   /**
+    * FIXME does not work if element is inside of form with prependId="false"
+    */
+   private boolean isAbsoluteClientIdPresent(String targetId, FacesContext facesContext)
+   {
+      return facesContext.getViewRoot().findComponent(targetId) != null;
+   }
+
+   private String getClientId(UIComponent component, String targetLocalId, FacesContext facesContext)
+   {
+      String currentLocalId = component.getId();
+      if (currentLocalId != null && currentLocalId.equals(targetLocalId))
+      {
+         return component.getClientId(facesContext);
+      }
+      else
+      {
+         Iterator<UIComponent> iter = component.getFacetsAndChildren();
+         while (iter.hasNext())
+         {
+            String clientId = getClientId(iter.next(), targetLocalId, facesContext);
+            if (clientId != null)
+            {
+               return clientId;
+            }
+         }
+         return null;
+      }
+   }
+   
+}

Added: modules/trunk/faces/src/main/java/org/jboss/seam/faces/resources/FacesResourceLoader.java
===================================================================
--- modules/trunk/faces/src/main/java/org/jboss/seam/faces/resources/FacesResourceLoader.java	                        (rev 0)
+++ modules/trunk/faces/src/main/java/org/jboss/seam/faces/resources/FacesResourceLoader.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,77 @@
+package org.jboss.seam.faces.resources;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import javax.enterprise.inject.Current;
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.beans.RuntimeSelected;
+import org.jboss.seam.beans.RuntimeSelectedBean;
+import org.jboss.seam.resources.DefaultResourceLoader;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+
+/**
+ * Extend the {@link DefaultResourceLoader} in the JSF environment to first
+ * attempt to locate the resource in the web root.
+ * 
+ * @author Dan Allen
+ */
+public
+ at RuntimeSelected
+class FacesResourceLoader extends DefaultResourceLoader implements RuntimeSelectedBean
+{
+   private static final LogProvider log = Logging.getLogProvider(FacesResourceLoader.class);
+   
+   @Current FacesContext facesContext;
+   @Current Locale locale;
+   
+   public boolean isActive()
+   {
+      // FIXME temporary hack since facesContext is not injecting correctly into this class
+      facesContext = FacesContext.getCurrentInstance();
+      return facesContext != null && facesContext.getCurrentPhaseId() != null && facesContext.getExternalContext() != null;
+   }
+
+   @Override
+   protected ResourceBundle loadBundleInternal(String bundleName)
+   {
+      return ResourceBundle.getBundle(bundleName, locale, Thread.currentThread().getContextClassLoader());
+   }
+
+   @Override
+   protected URL getResourceInternal(String absolutePath, String relativePath)
+   {
+      URL url = null;
+      try
+      {
+         url = facesContext.getExternalContext().getResource(absolutePath);
+      }
+      catch (MalformedURLException e) {}
+      
+      if (url != null)
+      {
+         log.debug("Loaded resource from servlet context: " + url);
+         return url;
+      }
+      
+      return super.getResourceInternal(absolutePath, relativePath);
+   }
+   
+   @Override
+   protected InputStream getResourceAsStreamInternal(String absolutePath, String relativePath)
+   {
+      InputStream stream = facesContext.getExternalContext().getResourceAsStream(absolutePath);
+      if (stream != null)
+      {
+         log.debug("Loaded resource stream from servlet context: " + absolutePath);
+      }
+      
+      return super.getResourceAsStreamInternal(absolutePath, relativePath);
+   }
+
+}

Modified: modules/trunk/faces/src/main/resources/META-INF/seam-faces.taglib.xml
===================================================================
--- modules/trunk/faces/src/main/resources/META-INF/seam-faces.taglib.xml	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/faces/src/main/resources/META-INF/seam-faces.taglib.xml	2009-05-28 19:13:06 UTC (rev 11026)
@@ -8,7 +8,7 @@
       <tag-name>restrictView</tag-name>
       <component>
          <component-type>org.jboss.seam.faces.RestrictView</component-type>
-         <handler-class>org.jboss.seam.faces.component.DeferredValueExpressionHandler</handler-class>
+         <handler-class>org.jboss.seam.faces.facelets.DeferredValueExpressionHandler</handler-class>
       </component>
    </tag>
    
@@ -16,7 +16,7 @@
       <tag-name>viewAction</tag-name>
       <component>
          <component-type>org.jboss.seam.faces.ViewAction</component-type>
-         <handler-class>org.jboss.seam.faces.component.ActionSourceHandler</handler-class>
+         <handler-class>org.jboss.seam.faces.facelets.ActionSourceHandler</handler-class>
       </component>
    </tag>
 

Deleted: modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesContextProducerTest.java
===================================================================
--- modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesContextProducerTest.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesContextProducerTest.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,50 +0,0 @@
-package org.jboss.seam.faces;
-
-import javax.faces.context.FacesContext;
-import org.jboss.seam.mock.faces.MockFacesContext;
-import static org.testng.Assert.*;
-
-import org.jboss.testharness.impl.packaging.Artifact;
-import org.jboss.testharness.impl.packaging.Classes;
-import org.jboss.webbeans.test.AbstractWebBeansTest;
-import org.testng.annotations.Test;
-
-/**
- * Verify that the FacesContextProducer produces the same FacesContext
- * as returned by FacesContext#getCurrentInstance().
- *
- * @author Dan Allen
- */
- at Artifact(addCurrentPackage = false)
- at Classes(FacesContextProducer.class)
-public class FacesContextProducerTest extends AbstractWebBeansTest
-{
-   @Override
-   public void beforeMethod()
-   {
-      super.beforeMethod();
-      installFacesContext();
-   }
-
-   @Test
-   public void testProduceCurrentFacesContext()
-   {
-      FacesContext actualFacesContext = FacesContext.getCurrentInstance();
-      FacesContextProducer standaloneProducer = new FacesContextProducer();
-      assertSame(standaloneProducer.getFacesContext(), actualFacesContext);
-      assertSame(getFacesContextInstance(), actualFacesContext);
-   }
-
-   private void installFacesContext()
-   {
-      new MockFacesContext().setCurrent();
-   }
-
-   /**
-    * Retrieve the FacesContextProducer instance
-    */
-   private FacesContext getFacesContextInstance()
-   {
-      return getCurrentManager().getInstanceByType(FacesContext.class);
-   }
-}

Deleted: modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesExpressionsTest.java
===================================================================
--- modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesExpressionsTest.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesExpressionsTest.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,62 +0,0 @@
-package org.jboss.seam.faces;
-
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
-
-import javax.el.CompositeELResolver;
-import javax.faces.context.FacesContext;
-import javax.faces.event.PhaseId;
-
-import org.jboss.seam.el.Expressions;
-import org.jboss.seam.el.ExpressionsProducer;
-import org.jboss.seam.el.SeamEL;
-import org.jboss.seam.mock.faces.MockFacesContext;
-import org.jboss.testharness.impl.packaging.Artifact;
-import org.jboss.testharness.impl.packaging.Classes;
-import org.jboss.webbeans.test.AbstractWebBeansTest;
-import org.testng.annotations.Test;
-
-/**
- * First and foremost, ensure that FacesExpressions is configured properly
- * to specialize Expressions and will thus load successfully. Once loaded,
- * verify that Expressions adds the appropriate JSF-specific functionality.
- *
- * @author Dan Allen
- */
- at Artifact(addCurrentPackage = false)
- at Classes(
-{
-   FacesExpressions.class, Expressions.class, ExpressionsProducer.class
-})
-public class FacesExpressionsTest extends AbstractWebBeansTest
-{
-   @Override
-   public void beforeMethod()
-   {
-      super.beforeMethod();
-      installMockFacesContext();
-   }
-
-   @Test
-   public void testUsesELFromFacesContext()
-   {
-      FacesContext facesContext = FacesContext.getCurrentInstance();
-      facesContext.setCurrentPhaseId(PhaseId.RENDER_RESPONSE);
-      Expressions expressions = getExpressionInstance();
-      assertSame(expressions.getELContext(), facesContext.getELContext());
-   }
-
-   private Expressions getExpressionInstance()
-   {
-      Expressions expressions = getCurrentManager().getInstanceByType(Expressions.class);
-      assertTrue(expressions instanceof FacesExpressions);
-      return expressions;
-   }
-
-   private void installMockFacesContext()
-   {
-      MockFacesContext facesContext = new MockFacesContext();
-      facesContext.setELContext(SeamEL.createELContext(new CompositeELResolver()));
-      facesContext.setCurrent();
-   }
-}

Deleted: modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesMessagesTest.java
===================================================================
--- modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesMessagesTest.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesMessagesTest.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,152 +0,0 @@
-package org.jboss.seam.faces;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertSame;
-
-import java.util.List;
-
-import javax.enterprise.inject.AnnotationLiteral;
-import javax.faces.application.FacesMessage;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIInput;
-import javax.faces.component.UINamingContainer;
-import javax.faces.component.UIViewRoot;
-import javax.faces.context.FacesContext;
-import javax.faces.event.PhaseId;
-
-import org.jboss.seam.el.Expressions;
-import org.jboss.seam.el.ExpressionsProducer;
-import org.jboss.seam.international.Interpolator;
-import org.jboss.seam.international.LocaleProducer;
-import org.jboss.seam.international.StatusMessage;
-import org.jboss.seam.international.StatusMessages;
-import org.jboss.seam.mock.faces.MockApplication;
-import org.jboss.seam.mock.faces.MockFacesContext;
-import org.jboss.testharness.impl.packaging.Artifact;
-import org.jboss.testharness.impl.packaging.Classes;
-import org.jboss.webbeans.context.ConversationContext;
-import org.jboss.webbeans.context.api.helpers.ConcurrentHashMapBeanStore;
-import org.jboss.webbeans.test.AbstractWebBeansTest;
-import org.testng.annotations.Test;
-
-/**
- * First and foremost, ensure that FacesMessage is configured properly to wrap
- * the StatusMessages component. Once loaded, verify that FacesMessages adds the
- * appropriate JSF-specific functionality to the conversation-scoped
- * StatusMessages repository.
- * 
- * @author Dan Allen
- * 
- * @see FacesMessages
- * @see StatusMessages
- */
- at Artifact(addCurrentPackage = false)
- at Classes(
-{
-   FacesMessages.class, StatusMessages.class, Interpolator.class, Expressions.class, ExpressionsProducer.class, LocaleProducer.class
-})
-public class FacesMessagesTest extends AbstractWebBeansTest
-{
-   @Override
-   public void beforeMethod()
-   {
-      super.beforeMethod();
-      activateConversationContext();
-      installMockFacesContext();
-   }
-
-   /**
-    * Test that the StatusMessage objects properly tranfer to FacesMessage objects
-    * upon the call to FacesMessages#onBeforeRender().
-    */
-   @Test
-   public void testGlobalStatusMessagesGetTransferedToFacesMessages()
-   {
-      FacesContext facesContext = FacesContext.getCurrentInstance();
-      facesContext.setCurrentPhaseId(PhaseId.INVOKE_APPLICATION);
-      StatusMessages statusMessages = getStatusMessagesInstance();
-
-      statusMessages.add("You've booked a night at {0}. Bon chance!", "Mandalay Bay");
-
-      assertEquals(statusMessages.getGlobalMessages().size(), 1);
-      assertEquals(facesContext.getMessageList().size(), 0);
-
-      facesContext.setCurrentPhaseId(PhaseId.RENDER_RESPONSE);
-      statusMessages.onBeforeRender();
-
-      assertEquals(statusMessages.getGlobalMessages().size(), 0);
-      assertEquals(facesContext.getMessageList().size(), 1);
-      assertEquals(facesContext.getMessageList(null).size(), 1);
-      FacesMessage facesMessage = facesContext.getMessageList().get(0);
-      assertEquals(facesMessage.getSeverity(), FacesMessage.SEVERITY_INFO);
-      assertEquals(facesMessage.getSummary(), "You've booked a night at Mandalay Bay. Bon chance!");
-      // NOTE this assignment happens inside the FacesMessage implementation
-      assertEquals(facesMessage.getSummary(), facesMessage.getDetail());
-   }
-
-   /**
-    * Verify that a message can be added to a control based on either it's absolute client id
-    * or it's local id. Verify that if the component cannot be found, a global message is created.
-    */
-   @Test
-   public void testStatusMessagesForControlGetTransferedToFacesMessages()
-   {
-      FacesContext facesContext = FacesContext.getCurrentInstance();
-
-      facesContext.setCurrentPhaseId(PhaseId.RESTORE_VIEW);
-      UIViewRoot viewRoot = new UIViewRoot();
-      UIComponent form = new UINamingContainer();
-      form.setId("form");
-      UIComponent input = new UIInput();
-      input.setId("input");
-      form.getChildren().add(input);
-      viewRoot.getChildren().add(form);
-      facesContext.setViewRoot(viewRoot);
-
-      facesContext.setCurrentPhaseId(PhaseId.INVOKE_APPLICATION);
-      StatusMessages statusMessages = getStatusMessagesInstance();
-      statusMessages.addToControl("input", StatusMessage.Severity.WARN, "First validation message for input");
-      statusMessages.addToControl("form:input", StatusMessage.Severity.WARN, "Second validation message for input");
-      statusMessages.addToControl("NO_SUCH_ID", StatusMessage.Severity.WARN, "Validation message that becomes global");
-
-      assertEquals(statusMessages.getKeyedMessages().size(), 3);
-      assertEquals(facesContext.getMessageList().size(), 0);
-
-      facesContext.setCurrentPhaseId(PhaseId.RENDER_RESPONSE);
-      statusMessages.onBeforeRender();
-
-      assertEquals(statusMessages.getGlobalMessages().size(), 0);
-      assertEquals(facesContext.getMessageList().size(), 3);
-      assertEquals(facesContext.getMessageList(null).size(), 1);
-      FacesMessage globalMessage = facesContext.getMessageList(null).get(0);
-      assertSame(globalMessage.getSeverity(), FacesMessage.SEVERITY_WARN);
-      assertEquals(globalMessage.getSummary(), "Validation message that becomes global");
-      List<FacesMessage> messagesForInput = facesContext.getMessageList("form:input");
-      assertEquals(messagesForInput.size(), 2);
-      assertEquals(messagesForInput.get(0).getSummary(), "First validation message for input");
-      assertEquals(messagesForInput.get(1).getSummary(), "Second validation message for input");
-   }
-
-   // TODO either test TransferStatusMessagesListener here or create a dedicated test for it; to test lookup of StatusMessages from listener
-
-   private void installMockFacesContext()
-   {
-      new MockFacesContext(new MockApplication(), true).setCurrent();
-   }
-
-   private void activateConversationContext()
-   {
-      ConversationContext.instance().setBeanStore(new ConcurrentHashMapBeanStore());
-      ConversationContext.instance().setActive(true);
-   }
-
-   /**
-    * Retrieve the StatusMessage instance, which is expected to be the type FacesMessages.
-    */
-   private StatusMessages getStatusMessagesInstance()
-   {
-      StatusMessages statusMessages = getCurrentManager().getInstanceByType(StatusMessages.class, new AnnotationLiteral<Faces>() {});
-      assert statusMessages instanceof FacesMessages;
-      return statusMessages;
-   }
-}

Copied: modules/trunk/faces/src/test/java/org/jboss/seam/faces/context/FacesContextProducerTest.java (from rev 10994, modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesContextProducerTest.java)
===================================================================
--- modules/trunk/faces/src/test/java/org/jboss/seam/faces/context/FacesContextProducerTest.java	                        (rev 0)
+++ modules/trunk/faces/src/test/java/org/jboss/seam/faces/context/FacesContextProducerTest.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,55 @@
+package org.jboss.seam.faces.context;
+
+import static org.testng.Assert.assertSame;
+
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+import org.jboss.seam.mock.faces.MockFacesContext;
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.Classes;
+import org.jboss.webbeans.test.AbstractWebBeansTest;
+import org.testng.annotations.Test;
+
+/**
+ * Verify that the FacesContextProducer produces the same FacesContext
+ * as returned by FacesContext#getCurrentInstance().
+ *
+ * @author Dan Allen
+ */
+ at Artifact(addCurrentPackage = false)
+ at Classes(FacesContextProducer.class)
+public class FacesContextProducerTest extends AbstractWebBeansTest
+{
+   @Override
+   public void beforeMethod()
+   {
+      super.beforeMethod();
+      installFacesContext();
+   }
+
+   @Test
+   public void testProduceCurrentFacesContext()
+   {
+      FacesContext actualFacesContext = FacesContext.getCurrentInstance();
+      FacesContextProducer standaloneProducer = new FacesContextProducer();
+      assertSame(standaloneProducer.getFacesContext(), actualFacesContext);
+      
+      FacesContext producedFacesContext = getFacesContextInstance();
+      assertSame(producedFacesContext, actualFacesContext);
+      assertSame(producedFacesContext.getCurrentPhaseId(), PhaseId.RENDER_RESPONSE);
+   }
+
+   private void installFacesContext()
+   {
+      new MockFacesContext().setCurrent().setCurrentPhaseId(PhaseId.RENDER_RESPONSE);
+   }
+
+   /**
+    * Retrieve the FacesContextProducer instance
+    */
+   private FacesContext getFacesContextInstance()
+   {
+      return getCurrentManager().getInstanceByType(FacesContext.class);
+   }
+}

Copied: modules/trunk/faces/src/test/java/org/jboss/seam/faces/el/FacesExpressionsTest.java (from rev 11012, modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesExpressionsTest.java)
===================================================================
--- modules/trunk/faces/src/test/java/org/jboss/seam/faces/el/FacesExpressionsTest.java	                        (rev 0)
+++ modules/trunk/faces/src/test/java/org/jboss/seam/faces/el/FacesExpressionsTest.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,61 @@
+package org.jboss.seam.faces.el;
+
+import static org.testng.Assert.assertSame;
+
+import javax.el.CompositeELResolver;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+import org.jboss.seam.el.Expressions;
+import org.jboss.seam.el.ExpressionsProducer;
+import org.jboss.seam.el.SeamEL;
+import org.jboss.seam.faces.context.FacesContextProducer;
+import org.jboss.seam.mock.faces.MockFacesContext;
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.Classes;
+import org.jboss.webbeans.test.AbstractWebBeansTest;
+import org.testng.annotations.Test;
+
+/**
+ * First and foremost, ensure that FacesExpressions is configured properly
+ * to specialize Expressions and will thus load successfully. Once loaded,
+ * verify that Expressions adds the appropriate JSF-specific functionality.
+ *
+ * @author Dan Allen
+ */
+ at Artifact(addCurrentPackage = false)
+ at Classes(
+{
+   FacesExpressions.class, Expressions.class, ExpressionsProducer.class, FacesContextProducer.class
+})
+public class FacesExpressionsTest extends AbstractWebBeansTest
+{
+   @Override
+   public void beforeMethod()
+   {
+      super.beforeMethod();
+      installMockFacesContext();
+   }
+
+   @Test
+   public void testUsesELFromFacesContext()
+   {
+      FacesContext facesContext = FacesContext.getCurrentInstance();
+      facesContext.setCurrentPhaseId(PhaseId.RENDER_RESPONSE);
+      Expressions expressions = getExpressionInstance();
+      assertSame(expressions.getELContext(), facesContext.getELContext());
+   }
+
+   private Expressions getExpressionInstance()
+   {
+      // we can't check that we have a FacesExpressions because it is hidden behind a proxy object
+      return getCurrentManager().getInstanceByType(Expressions.class);
+   }
+
+   private void installMockFacesContext()
+   {
+      MockFacesContext facesContext = new MockFacesContext();
+      facesContext.setELContext(SeamEL.createELContext(new CompositeELResolver()));
+      facesContext.setCurrent();
+   }
+}

Added: modules/trunk/faces/src/test/java/org/jboss/seam/faces/international/FacesLocaleProducerTest.java
===================================================================
--- modules/trunk/faces/src/test/java/org/jboss/seam/faces/international/FacesLocaleProducerTest.java	                        (rev 0)
+++ modules/trunk/faces/src/test/java/org/jboss/seam/faces/international/FacesLocaleProducerTest.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,53 @@
+package org.jboss.seam.faces.international;
+
+import static org.testng.Assert.assertSame;
+
+import java.util.Locale;
+
+import javax.faces.component.UIViewRoot;
+import javax.faces.event.PhaseId;
+
+import org.jboss.seam.el.SeamEL;
+import org.jboss.seam.faces.context.FacesContextProducer;
+import org.jboss.seam.international.LocaleProducer;
+import org.jboss.seam.international.LocaleResolver;
+import org.jboss.seam.international.LocaleResolverProducer;
+import org.jboss.seam.mock.faces.MockFacesContext;
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.Classes;
+import org.jboss.webbeans.test.AbstractWebBeansTest;
+import org.testng.annotations.Test;
+
+ at Artifact(addCurrentPackage = false)
+ at Classes({LocaleProducer.class, LocaleResolver.class, LocaleResolverProducer.class, FacesLocaleResolver.class, FacesContextProducer.class})
+public class FacesLocaleProducerTest extends AbstractWebBeansTest
+{
+   @Override
+   public void beforeMethod()
+   {
+      installMockFacesContext();
+   }
+   
+   @Test
+   public void testGetLocaleFromViewRoot()
+   {
+      assertSame(getLocaleInstance(), Locale.FRANCE);
+   }
+   
+   public Locale getLocaleInstance()
+   {
+      return getCurrentManager().getInstanceByType(Locale.class);
+   }
+   
+   private void installMockFacesContext()
+   {
+      MockFacesContext facesContext = new MockFacesContext();
+      facesContext.setCurrentPhaseId(PhaseId.RENDER_RESPONSE);
+      facesContext.setCurrent();
+      // must have ELContext set to set the locale on the UIViewRoot
+      facesContext.setELContext(SeamEL.createELContext());
+      UIViewRoot viewRoot = new UIViewRoot();
+      viewRoot.setLocale(Locale.FRANCE);
+      facesContext.setViewRoot(viewRoot);
+   }
+}

Copied: modules/trunk/faces/src/test/java/org/jboss/seam/faces/international/FacesMessagesTest.java (from rev 11012, modules/trunk/faces/src/test/java/org/jboss/seam/faces/FacesMessagesTest.java)
===================================================================
--- modules/trunk/faces/src/test/java/org/jboss/seam/faces/international/FacesMessagesTest.java	                        (rev 0)
+++ modules/trunk/faces/src/test/java/org/jboss/seam/faces/international/FacesMessagesTest.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,156 @@
+package org.jboss.seam.faces.international;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertSame;
+
+import java.util.List;
+
+import javax.enterprise.inject.AnnotationLiteral;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.component.UINamingContainer;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+import org.jboss.seam.el.Expressions;
+import org.jboss.seam.el.ExpressionsProducer;
+import org.jboss.seam.faces.Faces;
+import org.jboss.seam.international.Interpolator;
+import org.jboss.seam.international.LocaleProducer;
+import org.jboss.seam.international.LocaleResolver;
+import org.jboss.seam.international.LocaleResolverProducer;
+import org.jboss.seam.international.StatusMessage;
+import org.jboss.seam.international.StatusMessages;
+import org.jboss.seam.mock.faces.MockApplication;
+import org.jboss.seam.mock.faces.MockFacesContext;
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.Classes;
+import org.jboss.webbeans.context.ConversationContext;
+import org.jboss.webbeans.context.api.helpers.ConcurrentHashMapBeanStore;
+import org.jboss.webbeans.test.AbstractWebBeansTest;
+import org.testng.annotations.Test;
+
+/**
+ * First and foremost, ensure that FacesMessage is configured properly to wrap
+ * the StatusMessages component. Once loaded, verify that FacesMessages adds the
+ * appropriate JSF-specific functionality to the conversation-scoped
+ * StatusMessages repository.
+ * 
+ * @author Dan Allen
+ * 
+ * @see FacesMessages
+ * @see StatusMessages
+ */
+ at Artifact(addCurrentPackage = false)
+ at Classes(
+{
+   FacesMessages.class, StatusMessages.class, Interpolator.class, Expressions.class, ExpressionsProducer.class,
+   LocaleProducer.class, LocaleResolver.class, LocaleResolverProducer.class
+})
+public class FacesMessagesTest extends AbstractWebBeansTest
+{
+   @Override
+   public void beforeMethod()
+   {
+      super.beforeMethod();
+      activateConversationContext();
+      installMockFacesContext();
+   }
+
+   /**
+    * Test that the StatusMessage objects properly tranfer to FacesMessage objects
+    * upon the call to FacesMessages#onBeforeRender().
+    */
+   @Test
+   public void testGlobalStatusMessagesGetTransferedToFacesMessages()
+   {
+      FacesContext facesContext = FacesContext.getCurrentInstance();
+      facesContext.setCurrentPhaseId(PhaseId.INVOKE_APPLICATION);
+      StatusMessages statusMessages = getStatusMessagesInstance();
+
+      statusMessages.add("You've booked a night at {0}. Bon chance!", "Mandalay Bay");
+
+      assertEquals(statusMessages.getGlobalMessages().size(), 1);
+      assertEquals(facesContext.getMessageList().size(), 0);
+
+      facesContext.setCurrentPhaseId(PhaseId.RENDER_RESPONSE);
+      statusMessages.onBeforeRender();
+
+      assertEquals(statusMessages.getGlobalMessages().size(), 0);
+      assertEquals(facesContext.getMessageList().size(), 1);
+      assertEquals(facesContext.getMessageList(null).size(), 1);
+      FacesMessage facesMessage = facesContext.getMessageList().get(0);
+      assertEquals(facesMessage.getSeverity(), FacesMessage.SEVERITY_INFO);
+      assertEquals(facesMessage.getSummary(), "You've booked a night at Mandalay Bay. Bon chance!");
+      // NOTE this assignment happens inside the FacesMessage implementation
+      assertEquals(facesMessage.getSummary(), facesMessage.getDetail());
+   }
+
+   /**
+    * Verify that a message can be added to a control based on either it's absolute client id
+    * or it's local id. Verify that if the component cannot be found, a global message is created.
+    */
+   @Test
+   public void testStatusMessagesForControlGetTransferedToFacesMessages()
+   {
+      FacesContext facesContext = FacesContext.getCurrentInstance();
+
+      facesContext.setCurrentPhaseId(PhaseId.RESTORE_VIEW);
+      UIViewRoot viewRoot = new UIViewRoot();
+      UIComponent form = new UINamingContainer();
+      form.setId("form");
+      UIComponent input = new UIInput();
+      input.setId("input");
+      form.getChildren().add(input);
+      viewRoot.getChildren().add(form);
+      facesContext.setViewRoot(viewRoot);
+
+      facesContext.setCurrentPhaseId(PhaseId.INVOKE_APPLICATION);
+      StatusMessages statusMessages = getStatusMessagesInstance();
+      statusMessages.addToControl("input", StatusMessage.Severity.WARN, "First validation message for input");
+      statusMessages.addToControl("form:input", StatusMessage.Severity.WARN, "Second validation message for input");
+      statusMessages.addToControl("NO_SUCH_ID", StatusMessage.Severity.WARN, "Validation message that becomes global");
+
+      assertEquals(statusMessages.getKeyedMessages().size(), 3);
+      assertEquals(facesContext.getMessageList().size(), 0);
+
+      facesContext.setCurrentPhaseId(PhaseId.RENDER_RESPONSE);
+      statusMessages.onBeforeRender();
+
+      assertEquals(statusMessages.getGlobalMessages().size(), 0);
+      assertEquals(facesContext.getMessageList().size(), 3);
+      assertEquals(facesContext.getMessageList(null).size(), 1);
+      FacesMessage globalMessage = facesContext.getMessageList(null).get(0);
+      assertSame(globalMessage.getSeverity(), FacesMessage.SEVERITY_WARN);
+      assertEquals(globalMessage.getSummary(), "Validation message that becomes global");
+      List<FacesMessage> messagesForInput = facesContext.getMessageList("form:input");
+      assertEquals(messagesForInput.size(), 2);
+      assertEquals(messagesForInput.get(0).getSummary(), "First validation message for input");
+      assertEquals(messagesForInput.get(1).getSummary(), "Second validation message for input");
+   }
+
+   // TODO either test TransferStatusMessagesListener here or create a dedicated test for it; to test lookup of StatusMessages from listener
+
+   private void installMockFacesContext()
+   {
+      new MockFacesContext(new MockApplication(), true).setCurrent();
+   }
+
+   private void activateConversationContext()
+   {
+      ConversationContext.instance().setBeanStore(new ConcurrentHashMapBeanStore());
+      ConversationContext.instance().setActive(true);
+   }
+
+   /**
+    * Retrieve the StatusMessage instance, which is expected to be the type FacesMessages.
+    */
+   private StatusMessages getStatusMessagesInstance()
+   {
+      StatusMessages statusMessages = getCurrentManager().getInstanceByType(StatusMessages.class, new AnnotationLiteral<Faces>() {});
+      assert statusMessages instanceof FacesMessages;
+      return statusMessages;
+   }
+}

Modified: modules/trunk/faces/src/test/resources/test-suite.xml
===================================================================
--- modules/trunk/faces/src/test/resources/test-suite.xml	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/faces/src/test/resources/test-suite.xml	2009-05-28 19:13:06 UTC (rev 11026)
@@ -9,7 +9,7 @@
       </method-selectors>
       -->
       <packages>
-         <package name="org.jboss.seam.faces"/>
+         <package name="org.jboss.seam.faces.*"/>
       </packages>
    </test>
 </suite>

Modified: modules/trunk/international/pom.xml
===================================================================
--- modules/trunk/international/pom.xml	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/international/pom.xml	2009-05-28 19:13:06 UTC (rev 11026)
@@ -34,10 +34,20 @@
 
       <dependency>
          <groupId>${seam.groupId}</groupId>
+         <artifactId>seam-bridge-api</artifactId>
+      </dependency>
+
+      <dependency>
+         <groupId>${seam.groupId}</groupId>
          <artifactId>seam-el</artifactId>
       </dependency>
 
       <dependency>
+         <groupId>${seam.groupId}</groupId>
+         <artifactId>seam-resources</artifactId>
+      </dependency>
+
+      <dependency>
          <groupId>${webbeans.groupId}</groupId>
          <artifactId>jsr299-api</artifactId>
          <scope>provided</scope>

Added: modules/trunk/international/src/main/java/org/jboss/seam/international/AutoInterpolatedMessages.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/AutoInterpolatedMessages.java	                        (rev 0)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/AutoInterpolatedMessages.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,28 @@
+package org.jboss.seam.international;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.enterprise.inject.BindingType;
+
+/**
+ * Binding type for messages
+ * 
+ * @author Shane Bryzak
+ */
+ at Target( { TYPE, METHOD, PARAMETER, FIELD })
+ at Retention(RUNTIME)
+ at Documented
+ at BindingType
+ at Inherited
+public @interface AutoInterpolatedMessages
+{
+}

Copied: modules/trunk/international/src/main/java/org/jboss/seam/international/AutoInterpolatedMessagesProducer.java (from rev 10996, modules/trunk/international/src/main/java/org/jboss/seam/international/MessagesProducer.java)
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/AutoInterpolatedMessagesProducer.java	                        (rev 0)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/AutoInterpolatedMessagesProducer.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,19 @@
+package org.jboss.seam.international;
+
+import java.util.ResourceBundle;
+
+import javax.enterprise.inject.Named;
+import javax.enterprise.inject.Produces;
+
+public class AutoInterpolatedMessagesProducer
+{
+   public
+   @Produces
+   @Named("org.jboss.seam.international.messages")
+   //@RequestScoped
+   @AutoInterpolatedMessages
+   ResourceBundle getMessages(@Messages ResourceBundle messages, Interpolator interpolator)
+   {
+      return new InterpolatingResourceBundle(messages, interpolator);
+   }
+}

Added: modules/trunk/international/src/main/java/org/jboss/seam/international/InterpolatingResourceBundle.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/InterpolatingResourceBundle.java	                        (rev 0)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/InterpolatingResourceBundle.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,58 @@
+package org.jboss.seam.international;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class InterpolatingResourceBundle extends ResourceBundle
+{
+   private ResourceBundle delegate;
+   private Interpolator interpolator;
+
+   public InterpolatingResourceBundle(ResourceBundle delegate, Interpolator interpolator)
+   {
+      this.delegate = delegate;
+      this.interpolator = interpolator;
+   }
+
+   @Override
+   public Locale getLocale()
+   {
+      return delegate.getLocale();
+   }
+
+   @Override
+   public Enumeration<String> getKeys()
+   {
+      return delegate.getKeys();
+   }
+
+   @Override
+   protected Object handleGetObject(String key)
+   {
+      try
+      {
+         return interpolate(delegate.getObject(key));
+      }
+      catch (MissingResourceException mre)
+      {
+         // superclass will throw MissingResourceException if null is returned
+      }
+
+      return null;
+   }
+
+   protected Object interpolate(Object message)
+   {
+      if (message != null && message instanceof String)
+      {
+         return interpolator.interpolate((String) message);
+      }
+      else
+      {
+         return message;
+      }
+   }
+
+}

Modified: modules/trunk/international/src/main/java/org/jboss/seam/international/Interpolator.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/Interpolator.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/Interpolator.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -5,7 +5,7 @@
 import java.util.Locale;
 import java.util.StringTokenizer;
 
-import javax.enterprise.inject.Current;
+import javax.enterprise.inject.Initializer;
 
 import org.jboss.seam.el.Expressions;
 import org.jboss.webbeans.log.LogProvider;
@@ -19,9 +19,19 @@
 public class Interpolator implements Serializable
 {
    private static final LogProvider log = Logging.getLogProvider(Interpolator.class);
+   
+   private Expressions expressions;
+   private Locale locale;
 
-   @Current Expressions expressions;
-   @Current Locale locale;
+   public Interpolator() {}
+   
+   public
+   @Initializer
+   Interpolator(Expressions expressions, Locale locale)
+   {
+      this.expressions = expressions;
+      this.locale = locale;
+   }
 
    /**
     * Replace all EL expressions in the form #{...} with their evaluated

Modified: modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleProducer.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleProducer.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleProducer.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,5 +1,7 @@
 package org.jboss.seam.international;
 
+import java.util.Locale;
+
 import javax.enterprise.inject.Named;
 import javax.enterprise.inject.Produces;
 
@@ -15,8 +17,8 @@
    public
    @Produces
    @Named("org.jboss.seam.international.locale")
-   java.util.Locale getLocale()
+   Locale getLocale(LocaleResolver localeResolver)
    {
-      return java.util.Locale.getDefault();
+      return localeResolver.getLocale();
    }
 }

Added: modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleResolver.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleResolver.java	                        (rev 0)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleResolver.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,15 @@
+package org.jboss.seam.international;
+
+import java.util.Locale;
+
+import org.jboss.seam.beans.Default;
+
+public
+ at Default
+class LocaleResolver
+{
+   public Locale getLocale()
+   {
+      return Locale.getDefault();
+   }
+}

Added: modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleResolverProducer.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleResolverProducer.java	                        (rev 0)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/LocaleResolverProducer.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,32 @@
+package org.jboss.seam.international;
+
+import javax.enterprise.inject.Initializer;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.BeanManager;
+
+import org.jboss.seam.beans.RuntimeBeanSelector;
+
+public class LocaleResolverProducer extends RuntimeBeanSelector<LocaleResolver>
+{
+   LocaleResolverProducer() {}
+   
+   public @Initializer LocaleResolverProducer(BeanManager manager)
+   {
+      super(manager);
+   }
+   
+   @Override
+   public Class<LocaleResolver> getType()
+   {
+      return LocaleResolver.class;
+   }
+
+   @Override
+   public
+   @Produces
+   LocaleResolver selectImplementation()
+   {
+      return super.selectImplementation();
+   }
+   
+}

Modified: modules/trunk/international/src/main/java/org/jboss/seam/international/MessagesProducer.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/MessagesProducer.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/MessagesProducer.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,117 +1,21 @@
 package org.jboss.seam.international;
 
-import java.util.AbstractMap;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.MissingResourceException;
 import java.util.ResourceBundle;
-import java.util.Set;
 
-import javax.enterprise.context.RequestScoped;
-import javax.enterprise.inject.Named;
 import javax.enterprise.inject.Produces;
 
-/**
- * Factory for a Map that contains interpolated messages defined in the
- * Seam ResourceBundle.
- * 
- * @see SeamResourceBundle
- * 
- * @author Gavin King
- */
+import org.jboss.seam.resources.ResourceLoader;
+
 public class MessagesProducer
 {
-   //TODO: now we have ELResolver, it doesn't *have* to be a Map...
+   private String bundleName = "messages";
    
-   //@Current
-   ResourceBundle bundle;
-      
-   protected Map createMap()
-   {
-	  // AbstractMap uses the implementation of entrySet to perform all its
-	  // operations - for a resource bundle this is very inefficient for keys
-      return new AbstractMap<String, String>()
-      {
-         // FIXME disable temporarily
-         //private java.util.ResourceBundle bundle = ResourceBundleProducer.getBundle();
-         private java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("messages");
-
-         @Override
-         public String get(Object key)
-         {
-            if (key instanceof String)
-            {
-               String resourceKey = (String) key;
-               String resource=null;
-               if (bundle!=null)
-               {
-                  try
-                  {
-                     resource = bundle.getString(resourceKey);
-                  }
-                  catch (MissingResourceException mre)
-                  {
-                     //Just swallow
-                  }
-               }
-               return resource==null ? resourceKey : resource;
-            }
-            else
-            {
-               return null;
-            }
-         }
-         
-         @Override
-         public Set<Map.Entry<String, String>> entrySet()
-         {
-        	Enumeration<String> keys = bundle.getKeys();
-            Map<String, String> map = new HashMap<String, String>();
-            while ( keys.hasMoreElements() )
-            {
-               String key = keys.nextElement();
-               map.put( key, get(key) );
-            }
-            return Collections.unmodifiableSet(map.entrySet());
-         }
-
-         @Override
-         public boolean containsKey(Object key)
-         {
-            return get(key) != null;
-         }
-
-         @Override
-         public Set<String> keySet()
-         {
-            Enumeration<String> keys = bundle.getKeys();
-            return new HashSet<String>(Collections.list(keys));
-         }
-
-         @Override
-         public int size()
-         {
-            return keySet().size();
-         }
-         
-      };
-   }
-
-   /**
-    * Create the Map and cache it in the request scope. No need to cache
-    * it in the session scope, since it is inexpensive to create.
-    * 
-    * @return a Map that interpolates messages in the Seam ResourceBundle
-    */
+   public
    @Produces
-   @Named("org.jboss.seam.international.messages")
-   @RequestScoped
-   @Messages public Map<String, String> getMessages()
+   //@RequestScoped
+   @Messages
+   ResourceBundle getResourceBundle(ResourceLoader resourceLoader)
    {
-      return createMap();
+      return resourceLoader.loadBundle(bundleName);
    }
-   
 }

Deleted: modules/trunk/international/src/main/java/org/jboss/seam/international/ResourceBundle.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/ResourceBundle.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/ResourceBundle.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,28 +0,0 @@
-package org.jboss.seam.international;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import javax.enterprise.inject.BindingType;
-
-/**
- * The binding type for the Seam resource bundle.
- *
- * @author Dan Allen
- */
-public
- at Target( { TYPE, METHOD, PARAMETER, FIELD })
- at Retention(RUNTIME)
- at Documented
- at BindingType
- at Inherited
- at interface ResourceBundle {
-}

Deleted: modules/trunk/international/src/main/java/org/jboss/seam/international/ResourceLoader.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/ResourceLoader.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/ResourceLoader.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,186 +0,0 @@
-package org.jboss.seam.international;
-
-
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Locale;
-import java.util.MissingResourceException;
-
-import javax.enterprise.inject.spi.BeanManager;
-
-import org.jboss.webbeans.log.LogProvider;
-import org.jboss.webbeans.log.Logging;
-
-/**
- * Access to application resources and resource bundles.
- * 
- * @author Gavin King
- */
-public class ResourceLoader
-{
-   private static final LogProvider log = Logging.getLogProvider(ResourceLoader.class);
-
-   private String[] bundleNames = { "messages" };
-
-   //@Current
-   BeanManager manager;
-   
-   /**
-    * The configurable list of delegate resource bundle names
-    * 
-    * @return an array of resource bundle names
-    */
-   public String[] getBundleNames()
-   {
-      return bundleNames;
-   }
-   
-   public void setBundleNames(String[] bundleNames)
-   {
-      this.bundleNames = bundleNames;
-   }
-   
-   public InputStream getResourceAsStream(String resource)
-   {
-      String relativePath = resource;
-      if (resource.startsWith("/"))
-      {
-         relativePath = resource.substring(1);
-      }
-      else
-      {
-         resource = "/" + resource;
-      }
-
-      return getResourceAsStream(resource, relativePath);
-   }
-
-   public URL getResource(String resource)
-   {
-      String relativePath = resource;
-      if (resource.startsWith("/"))
-      {
-         relativePath = resource.substring(1);
-      }
-      else
-      {
-         resource = "/" + resource;
-      }
-
-      return getResource(resource, relativePath);
-   }
-   
-   /**
-    * Load a resource bundle by name (may be overridden by subclasses
-    * who want to use non-standard resource bundle types).
-    * 
-    * @param bundleName the name of the resource bundle
-    * @return an instance of java.util.ResourceBundle
-    */
-   public java.util.ResourceBundle loadBundle(String bundleName)
-   {
-      try
-      {
-         java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle(
-               bundleName,
-               manager.getInstanceByType(Locale.class),
-               Thread.currentThread().getContextClassLoader()
-            );
-         log.debug("loaded resource bundle: " + bundleName);
-         return bundle;
-      }
-      catch (MissingResourceException mre)
-      {
-         log.debug("resource bundle missing: " + bundleName);
-         return null;
-      }
-   }
-   
-   @Override
-   public String toString()
-   {
-      StringBuilder report = new StringBuilder("bundleNames = {");
-      boolean first = true;
-      if (bundleNames != null)
-      {
-         for (Object bundleName : bundleNames)
-         {
-            if (first)
-            {
-               first = false;
-            }
-            else
-            {
-               report.append(", ");
-            }
-            report.append(bundleName);
-         }
-      }
-      report.append("}");
-
-      return "ResourceBundle(" + report + ")";
-   }
-
-   protected InputStream getResourceAsStream(String path, String relativePath)
-   {
-      InputStream stream = null;
-      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-      if (classLoader != null)
-      {
-         stream = classLoader.getResourceAsStream(relativePath);
-         if (stream != null)
-         {
-            log.debug("Loaded resource from context classloader: " + relativePath);
-            return stream;
-         }
-      }
-
-      stream = getClass().getResourceAsStream(path);
-      if (stream != null)
-      {
-         log.debug("Loaded resource from Seam classloader: " + path);
-         return stream;
-      }
-
-      stream = getClass().getClassLoader().getResourceAsStream(relativePath);
-      if (stream != null)
-      {
-         log.debug("Loaded resource from Seam classloader: " + relativePath);
-         return stream;
-      }
-
-      return stream;
-   }
-
-   protected URL getResource(String path, String relativePath)
-   {
-      URL url = null;
-      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-      if (classLoader != null)
-      {
-         url = classLoader.getResource(relativePath);
-         if (url != null)
-         {
-            log.debug("Loaded resource from context classloader: " + url);
-            return url;
-         }
-      }
-
-      url = getClass().getResource(path);
-      if (url != null)
-      {
-         log.debug("Loaded resource from Seam classloader: " + url);
-         return url;
-      }
-
-      url = getClass().getClassLoader().getResource(relativePath);
-      if (url != null)
-      {
-         log.debug("Loaded resource from Seam classloader: " + url);
-         return url;
-      }
-
-      return url;
-   }
-   
-}

Added: modules/trunk/international/src/main/java/org/jboss/seam/international/SeamResourceBundleAdapter.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/SeamResourceBundleAdapter.java	                        (rev 0)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/SeamResourceBundleAdapter.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,44 @@
+package org.jboss.seam.international;
+
+import java.util.Enumeration;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import javax.enterprise.inject.AnnotationLiteral;
+import javax.enterprise.inject.spi.BeanManager;
+
+import org.jboss.seam.bridge.ManagerBridge;
+
+public class SeamResourceBundleAdapter extends ResourceBundle
+{
+   @Override
+   public Enumeration<String> getKeys()
+   {
+      return getMessages().getKeys();
+   }
+
+   @Override
+   protected Object handleGetObject(String key)
+   {
+      try
+      {
+         return getMessages().getObject(key);
+      }
+      catch (MissingResourceException mre)
+      {
+         // superclass will throw MissingResourceException if null is returned
+      }
+
+      return null;
+   }
+
+   protected ResourceBundle getMessages()
+   {
+      return getCurrentManager().getInstanceByType(ResourceBundle.class, new AnnotationLiteral<AutoInterpolatedMessages>(){});
+   }
+
+   protected BeanManager getCurrentManager()
+   {
+      return ManagerBridge.getProvider().getCurrentManager();
+   }
+}

Modified: modules/trunk/international/src/main/java/org/jboss/seam/international/StatusMessage.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/StatusMessage.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/StatusMessage.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,4 +1,4 @@
-/* 
+/*
  * JBoss, Home of Professional Open Source
  * Copyright 2009, Red Hat Middleware LLC, and individual contributors
  * by the @authors tag. See the copyright.txt in the distribution for a
@@ -39,7 +39,6 @@
 {
    /**
     * The severity of the status message
-    *
     */
    public enum Severity
    {
@@ -48,6 +47,7 @@
       ERROR,
       FATAL;
    }
+   
    private String summaryTemplate;
    private String summary;
    private String detailTemplate;
@@ -55,20 +55,31 @@
    private Severity severity = Severity.INFO;
 
    /**
-    * Create 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.
-    * 
+    * Create a status message using the provided summary and detail templates.
+    * The severity is only assigned if a summary is provided. Note that te
+    * StatusMessages component is responsible for resolving templates from the
+    * message bundle.
     */
-   public StatusMessage(Severity severity, String key, String detailKey, String defaultMessageTemplate, String defaultMessageDetailTemplate)
+   public StatusMessage(Severity severity, String summaryTemplate, String detailTemplate)
    {
-      this.summaryTemplate = getBundleMessage(key, defaultMessageTemplate);
-      this.detailTemplate = getBundleMessage(detailKey, defaultMessageDetailTemplate);
+      this.summaryTemplate = summaryTemplate;
+      this.detailTemplate = detailTemplate;
       if (!Strings.isEmpty(summaryTemplate))
       {
          this.severity = severity;
       }
    }
+   
+   /**
+    * Create a status message using the summary template and a null detail
+    * template. The severity is only assigned if a summary is provided. Note
+    * that te StatusMessages component is responsible for resolving templates
+    * from the message bundle.
+    */
+   public StatusMessage(Severity severity, String template)
+   {
+      this(severity, template, null);
+   }
 
    public boolean isEmpty()
    {

Modified: modules/trunk/international/src/main/java/org/jboss/seam/international/StatusMessages.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/StatusMessages.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/StatusMessages.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -31,13 +31,20 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
 
 import javax.enterprise.context.ConversationScoped;
+import javax.enterprise.inject.AnnotationLiteral;
+import javax.enterprise.inject.Current;
 import javax.enterprise.inject.Initializer;
 import javax.enterprise.inject.Named;
+import javax.enterprise.inject.spi.BeanManager;
 import javax.validation.ConstraintViolation;
 
 import org.jboss.seam.international.StatusMessage.Severity;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
 
 /**
  * <p>{@link StatusMessages} is a technology agnostic repository for holding
@@ -68,6 +75,8 @@
 {
    private static final long serialVersionUID = -5396789975397138270L;
 
+   private static final LogProvider log = Logging.getLogProvider(StatusMessages.class);
+   
    private List<StatusMessage> messages = new ArrayList<StatusMessage>();
 
    private Map<String, List<StatusMessage>> keyedMessages = new HashMap<String, List<StatusMessage>>();
@@ -75,12 +84,17 @@
    private transient List<Runnable> tasks;
 
    private Interpolator interpolator;
+   
+   // FIXME the scoping may not be right unless resourceBundle updates internal (for instance per request)
+   //private ResourceBundle resourceBundle;
+   @Current BeanManager manager;
 
    public StatusMessages() {}
 
-   public @Initializer StatusMessages(Interpolator interpolator)
+   public @Initializer StatusMessages(Interpolator interpolator) //, @Messages ResourceBundle resourceBundle)
    {
       this.interpolator = interpolator;
+      //this.resourceBundle = resourceBundle;
    }
    
    /**
@@ -158,9 +172,9 @@
     * 
     * You can also specify the severity, and parameters to be interpolated
     */
-   public void add(Severity severity, String key, String detailKey, String messageTemplate, String messageDetailTemplate, final Object... params)
+   public void add(Severity severity, String summaryKey, String detailKey, String messageSummaryTemplate, String messageDetailTemplate, final Object... params)
    {
-      final StatusMessage message = new StatusMessage(severity, key, detailKey, messageTemplate, messageDetailTemplate);
+      final StatusMessage message = new StatusMessage(severity, getBundleMessage(summaryKey, messageSummaryTemplate), getBundleMessage(detailKey, messageDetailTemplate));
       if (!message.isEmpty())
       {
          messages.add(message);
@@ -178,11 +192,10 @@
     * layer implementation in use.
     * 
     * You can also specify the severity, and parameters to be interpolated
-    * 
     */
    public void addToControl(String id, Severity severity, String key, String messageTemplate, final Object... params)
    {
-      final StatusMessage message = new StatusMessage(severity, key, null, messageTemplate, null);
+      final StatusMessage message = new StatusMessage(severity, getBundleMessage(key, messageTemplate));
       if (!message.isEmpty())
       {
          if (keyedMessages.containsKey(id))
@@ -214,7 +227,6 @@
     * Create a new status message, with the messageTemplate is as the message.
     * 
     * You can also specify the severity, and parameters to be interpolated
-    * 
     */
    public void add(Severity severity, String messageTemplate, Object... params)
    {
@@ -230,7 +242,6 @@
     * 
     * A severity of WARN will be used, and you can specify parameters to be
     * interpolated
-    * 
     */
    public void addToControl(String id, String messageTemplate, Object... params)
    {
@@ -270,7 +281,6 @@
     * using the provided key.
     * 
     * You can also specify the severity, and parameters to be interpolated
-    * 
     */
    public void addFromResourceBundle(Severity severity, String key, Object... params)
    {
@@ -284,7 +294,6 @@
     * 
     * A severity of INFO will be used, and you can specify parameters to be
     * interpolated
-    * 
     */
    public void addFromResourceBundleOrDefault(String key, String defaultMessageTemplate, Object... params)
    {
@@ -297,7 +306,6 @@
     * the defaultMessageTemplate will be used.
     * 
     * You can also specify the severity, and parameters to be interpolated
-    * 
     */
    public void addFromResourceBundleOrDefault(Severity severity, String key, String defaultMessageTemplate, Object... params)
    {
@@ -314,7 +322,6 @@
     * 
     * A severity of WARN will be used, and you can specify parameters to be
     * interpolated
-    * 
     */
    public void addToControlFromResourceBundle(String id, String key, Object... params)
    {
@@ -330,7 +337,6 @@
     * layer implementation in use.
     * 
     * You can also specify the severity, and parameters to be interpolated
-    * 
     */
    public void addToControlFromResourceBundle(String id, Severity severity, String key, Object... params)
    {
@@ -348,7 +354,6 @@
     * 
     * A severity of WARN will be used, and you can specify parameters to be
     * interpolated
-    * 
     */
    public void addToControlFromResourceBundleOrDefault(String id, String key, String defaultMessageTemplate, Object... params)
    {
@@ -365,7 +370,6 @@
     * layer implementation in use.
     * 
     * You can also specify the severity, and parameters to be interpolated
-    * 
     */
    public void addToControlFromResourceBundleOrDefault(String id, Severity severity, String key, String defaultMessageTemplate, Object... params)
    {
@@ -440,6 +444,37 @@
       doRunTasks();
    }
 
+   protected String getBundleMessage(String key)
+   {
+      return getBundleMessage(key, key);
+   }
+   
+   protected String getBundleMessage(String key, String defaultMessageTemplate)
+   {
+      String messageTemplate = defaultMessageTemplate;
+      if (key != null)
+      {
+         // FIXME this is a hack because I can't inject it since ResourceBundle is not proxyable
+         if (manager.getBeans(ResourceBundle.class, new AnnotationLiteral<Messages>() {}).size() == 1)
+         {
+            ResourceBundle resourceBundle = manager.getInstanceByType(ResourceBundle.class, new AnnotationLiteral<Messages>() {});
+            try
+            {
+               String bundleMessage = resourceBundle.getString(key);
+               if (bundleMessage != null)
+               {
+                  messageTemplate = bundleMessage;
+               }
+            }
+            catch (MissingResourceException mre)
+            {
+               log.trace("Message key " + key + " was not defined in the Seam resource bundle. Using default message template");
+            }
+         }
+      }
+      return messageTemplate;
+   }
+   
    private List<Runnable> getTasks()
    {
       if (tasks == null)

Deleted: modules/trunk/international/src/main/java/org/jboss/seam/international/util/Resources.java
===================================================================
--- modules/trunk/international/src/main/java/org/jboss/seam/international/util/Resources.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/international/src/main/java/org/jboss/seam/international/util/Resources.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,177 +0,0 @@
-package org.jboss.seam.international.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import javax.servlet.ServletContext;
-
-import org.jboss.webbeans.log.LogProvider;
-import org.jboss.webbeans.log.Logging;
-
-public class Resources 
-{
-    private static final LogProvider log = Logging.getLogProvider(Resources.class);
-
-   public static InputStream getResourceAsStream(String resource, ServletContext servletContext) 
-   {
-      String stripped = resource.startsWith("/") ? 
-            resource.substring(1) : resource;
-   
-      InputStream stream = null; 
-
-      if (servletContext!=null) {
-         try {
-            stream = servletContext.getResourceAsStream(resource);
-            if (stream!=null) {
-                log.debug("Loaded resource from servlet context: " + resource);
-            }
-         } catch (Exception e) {       
-             //
-         }
-      }
-      
-      if (stream==null) {
-         stream = getResourceAsStream(resource, stripped);
-      }
-      
-      return stream;
-   }
-
-   public static URL getResource(String resource, ServletContext servletContext) 
-   {
-      if (!resource.startsWith("/"))
-      {
-         resource = "/" + resource;
-      }
-      
-      String stripped = resource.startsWith("/") ? 
-            resource.substring(1) : resource;
-   
-      URL url  = null; 
-
-      if (servletContext!=null)
-      {
-         try {
-            url = servletContext.getResource(resource);
-            log.debug("Loaded resource from servlet context: " + url);
-         } catch (Exception e) {
-             //
-         }
-      }
-      
-      if (url==null)
-      {
-        url = getResource(resource, stripped);
-      }
-      
-      return url;
-   }
-   
-   static InputStream getResourceAsStream(String resource, String stripped)
-   {
-      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-      InputStream stream = null;
-      if (classLoader!=null) {
-         stream = classLoader.getResourceAsStream(stripped);
-         if (stream !=null) {
-             log.debug("Loaded resource from context classloader: " + stripped);
-         }
-      }
-      
-      if (stream == null) {
-         stream = Resources.class.getResourceAsStream(resource);
-         if (stream !=null) {
-             log.debug("Loaded resource from Seam classloader: " + resource);
-         }
-      }
-      
-      if (stream == null) {
-         stream = Resources.class.getClassLoader().getResourceAsStream(stripped);
-         if (stream!=null) {
-             log.debug("Loaded resource from Seam classloader: " + stripped);
-         }
-      }
-      
-      return stream;
-   }
-   
-   static URL getResource(String resource, String stripped)
-   {
-       ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-       URL url = null;
-       if (classLoader!=null) {
-           url = classLoader.getResource(stripped);
-           if (url!=null) {
-               log.debug("Loaded resource from context classloader: " + url);
-           }
-       }
-
-       if (url == null) {
-           url = Resources.class.getResource(resource);
-           if (url!=null) {
-               log.debug("Loaded resource from Seam classloader: " + url);
-           }
-       }
-
-       if (url == null) {
-           url = Resources.class.getClassLoader().getResource(stripped);
-           if (url!=null) {
-               log.debug("Loaded resource from Seam classloader: " + url);
-           }           
-       }
-       
-       return url;
-   }
-
-   public static void closeStream(InputStream inputStream) {
-       if (inputStream == null) {
-           return;
-       }
-       
-       try {
-           inputStream.close();
-       } catch (IOException e) {
-          // 
-       }       
-   }
-   
-   public static File getRealFile(ServletContext servletContext, String path)
-   {
-      String realPath = servletContext.getRealPath(path);
-      if (realPath==null) //WebLogic!
-      {
-         try 
-         {
-            URL resourcePath = servletContext.getResource(path);
-            if ((resourcePath != null) && (resourcePath.getProtocol().equals("file"))) 
-            {
-               realPath = resourcePath.getPath();
-            }
-            else
-            {
-               log.warn("Unable to determine real path from servlet context for \"" + path + "\" path does not exist.");
-            }
-         }
-         catch (MalformedURLException e) 
-         {
-            log.warn("Unable to determine real path from servlet context for : " + path);
-            log.debug("Caused by MalformedURLException", e);
-         }
-
-      }
-      
-      if (realPath != null)
-      {
-         File file = new File(realPath);
-         if (file.exists())
-         {
-            return file;
-         }
-      }
-      return null;
-   }
-
-}
\ No newline at end of file

Added: modules/trunk/international/src/test/java/org/jboss/seam/international/AutoInterpolatedMessagesTest.java
===================================================================
--- modules/trunk/international/src/test/java/org/jboss/seam/international/AutoInterpolatedMessagesTest.java	                        (rev 0)
+++ modules/trunk/international/src/test/java/org/jboss/seam/international/AutoInterpolatedMessagesTest.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,56 @@
+package org.jboss.seam.international;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.ResourceBundle;
+
+import javax.el.CompositeELResolver;
+import javax.enterprise.inject.AnnotationLiteral;
+
+import org.jboss.seam.el.Expressions;
+import org.jboss.seam.el.ExpressionsProducer;
+import org.jboss.seam.resources.DefaultResourceLoader;
+import org.jboss.seam.resources.ResourceLoaderProducer;
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.Classes;
+import org.jboss.webbeans.el.WebBeansELResolver;
+import org.jboss.webbeans.test.AbstractWebBeansTest;
+import org.testng.annotations.Test;
+
+ at Artifact
+ at Classes({DefaultResourceLoader.class, ResourceLoaderProducer.class, Expressions.class, ExpressionsProducer.class})
+public class AutoInterpolatedMessagesTest extends AbstractWebBeansTest
+{
+   private boolean elResolverInitialized = false;
+   
+   @Override
+   public void beforeMethod()
+   {
+      super.beforeMethod();
+      if (!elResolverInitialized)
+      {
+         installWebBeansELResolver();
+      }
+   }
+   
+   @Test
+   public void testLoadMessages()
+   {
+      ResourceBundle messages = getMessages();
+      assertEquals(messages.getString("title"), "Hello Seam!");
+      assertEquals(messages.getString("thing"), "It's called music");
+   }
+   
+   private void installWebBeansELResolver()
+   {
+      Expressions expressions = getCurrentManager().getInstanceByType(Expressions.class);
+      // FIXME wow this is a hack
+      ((CompositeELResolver) expressions.getELContext().getELResolver()).add(new WebBeansELResolver());
+      elResolverInitialized = true;
+   }
+   
+   private ResourceBundle getMessages()
+   {
+      return getCurrentManager().getInstanceByType(ResourceBundle.class, new AnnotationLiteral<AutoInterpolatedMessages>() {});
+   }
+}

Modified: modules/trunk/international/src/test/java/org/jboss/seam/international/InterpolatorTest.java
===================================================================
--- modules/trunk/international/src/test/java/org/jboss/seam/international/InterpolatorTest.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/international/src/test/java/org/jboss/seam/international/InterpolatorTest.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -29,14 +29,19 @@
  * @see LocaleProducer
  */
 @Artifact(addCurrentPackage = false)
- at Classes({Interpolator.class, Expressions.class, ExpressionsProducer.class, LocaleProducer.class})
+ at Classes({Interpolator.class, Expressions.class, ExpressionsProducer.class, LocaleProducer.class, LocaleResolver.class, LocaleResolverProducer.class})
 public class InterpolatorTest extends AbstractWebBeansTest
 {
+   private boolean elResolverInitialized = false;
+   
    @Override
    public void beforeMethod()
    {
       super.beforeMethod();
-      installTestFixtureELResolver();
+      if (!elResolverInitialized)
+      {
+         installTestFixtureELResolver();
+      }
    }
 
    @Test
@@ -97,6 +102,7 @@
       Expressions expressions = getCurrentManager().getInstanceByType(Expressions.class);
       // FIXME wow this is a hack
       ((CompositeELResolver) expressions.getELContext().getELResolver()).add(new TestFixtureELResolver(fixture));
+      elResolverInitialized = true;
    }
 
    public class TestFixtureELResolver extends AbstractELResolver

Modified: modules/trunk/international/src/test/java/org/jboss/seam/international/LocaleProducerTest.java
===================================================================
--- modules/trunk/international/src/test/java/org/jboss/seam/international/LocaleProducerTest.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/international/src/test/java/org/jboss/seam/international/LocaleProducerTest.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -1,8 +1,11 @@
 package org.jboss.seam.international;
 
-import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertSame;
 
 import java.util.Locale;
+
 import org.jboss.testharness.impl.packaging.Artifact;
 import org.jboss.testharness.impl.packaging.Classes;
 import org.jboss.webbeans.test.AbstractWebBeansTest;
@@ -16,7 +19,7 @@
  * @author Dan Allen
  */
 @Artifact(addCurrentPackage = false)
- at Classes(LocaleProducer.class)
+ at Classes({LocaleProducer.class, LocaleResolver.class, LocaleResolverProducer.class})
 public class LocaleProducerTest extends AbstractWebBeansTest
 {
    /**
@@ -26,10 +29,14 @@
    @Test
    public void testProducerMethodReturnsJvmDefault()
    {
-      LocaleProducer producer = new LocaleProducer();
-      Locale result = producer.getLocale();
+      LocaleResolver resolver = new LocaleResolver();
+      Locale result = resolver.getLocale();
       assertNotNull(result);
       assertEquals(result.toString(), Locale.getDefault().toString());
+      
+      LocaleProducer producer = new LocaleProducer();
+      Locale result2 = producer.getLocale(resolver);
+      assertSame(result2, result);
    }
 
    /**

Modified: modules/trunk/international/src/test/java/org/jboss/seam/international/StatusMessagesTest.java
===================================================================
--- modules/trunk/international/src/test/java/org/jboss/seam/international/StatusMessagesTest.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/international/src/test/java/org/jboss/seam/international/StatusMessagesTest.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -4,6 +4,8 @@
 
 import org.jboss.seam.el.Expressions;
 import org.jboss.seam.el.ExpressionsProducer;
+import org.jboss.seam.resources.DefaultResourceLoader;
+import org.jboss.seam.resources.ResourceLoaderProducer;
 import org.jboss.testharness.impl.packaging.Artifact;
 import org.jboss.testharness.impl.packaging.Classes;
 import org.jboss.webbeans.context.ConversationContext;
@@ -20,7 +22,9 @@
 @Artifact(addCurrentPackage = false)
 @Classes(
 {
-   StatusMessages.class, Interpolator.class, Expressions.class, ExpressionsProducer.class, LocaleProducer.class
+   StatusMessages.class, Interpolator.class, Expressions.class, ExpressionsProducer.class,
+   LocaleProducer.class, LocaleResolver.class, LocaleResolverProducer.class, MessagesProducer.class,
+   DefaultResourceLoader.class, ResourceLoaderProducer.class
 })
 public class StatusMessagesTest extends AbstractWebBeansTest
 {

Added: modules/trunk/international/src/test/java/org/jboss/seam/international/Thing.java
===================================================================
--- modules/trunk/international/src/test/java/org/jboss/seam/international/Thing.java	                        (rev 0)
+++ modules/trunk/international/src/test/java/org/jboss/seam/international/Thing.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,13 @@
+package org.jboss.seam.international;
+
+import javax.enterprise.inject.Named;
+
+public
+ at Named
+class Thing
+{
+   public String getName()
+   {
+      return "music";
+   }
+}

Added: modules/trunk/international/src/test/resources/messages.properties
===================================================================
--- modules/trunk/international/src/test/resources/messages.properties	                        (rev 0)
+++ modules/trunk/international/src/test/resources/messages.properties	2009-05-28 19:13:06 UTC (rev 11026)
@@ -0,0 +1,2 @@
+title=Hello Seam!
+thing=It's called #{thing.name}

Modified: modules/trunk/parent/pom.xml
===================================================================
--- modules/trunk/parent/pom.xml	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/parent/pom.xml	2009-05-28 19:13:06 UTC (rev 11026)
@@ -94,6 +94,7 @@
       <module>../mock</module>
       <module>../bridge-api</module>
       <module>../beans</module>
+      <module>../resources</module>
       <module>../el</module>
       <module>../international</module>
       <module>../web</module>      

Modified: modules/trunk/resources/src/main/java/org/jboss/seam/resources/DefaultResourceLoader.java
===================================================================
--- modules/trunk/resources/src/main/java/org/jboss/seam/resources/DefaultResourceLoader.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/resources/src/main/java/org/jboss/seam/resources/DefaultResourceLoader.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -26,6 +26,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.MissingResourceException;
+import java.util.ResourceBundle;
 
 import org.jboss.seam.beans.Default;
 import org.jboss.webbeans.log.LogProvider;
@@ -38,6 +39,7 @@
  * Classloader isn't available
  * 
  * @author Pete Muir
+ * @author Dan Allen
  */
 public
 @Default
@@ -75,17 +77,17 @@
     * @param bundleName the name of the resource bundle
     * @return an instance of java.util.ResourceBundle
     */
-   public java.util.ResourceBundle loadBundle(String bundleName)
+   public ResourceBundle loadBundle(String bundleName)
    {
       try
       {
-         java.util.ResourceBundle bundle = loadBundleInternal(bundleName);
+         ResourceBundle bundle = loadBundleInternal(bundleName);
          log.debug("loaded resource bundle: " + bundleName);
          return bundle;
       }
       catch (MissingResourceException mre)
       {
-         log.debug("resource bundle missing: " + bundleName);
+         log.warn("resource bundle missing: " + bundleName);
          return null;
       }
    }
@@ -112,9 +114,9 @@
       }
    }
    
-   protected java.util.ResourceBundle loadBundleInternal(String bundleName)
+   protected ResourceBundle loadBundleInternal(String bundleName)
    {
-      return java.util.ResourceBundle.getBundle(bundleName, Locale.getDefault(), Thread.currentThread().getContextClassLoader());
+      return ResourceBundle.getBundle(bundleName, Locale.getDefault(), Thread.currentThread().getContextClassLoader());
    }
    
    protected InputStream getResourceAsStreamInternal(String absolutePath, String relativePath)

Modified: modules/trunk/resources/src/main/java/org/jboss/seam/resources/ResourceLoader.java
===================================================================
--- modules/trunk/resources/src/main/java/org/jboss/seam/resources/ResourceLoader.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/resources/src/main/java/org/jboss/seam/resources/ResourceLoader.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -16,7 +16,9 @@
  */
 package org.jboss.seam.resources;
 
+import java.io.InputStream;
 import java.net.URL;
+import java.util.ResourceBundle;
 
 /**
  * Resource loading/class creation services for Seam. By default an
@@ -51,4 +53,21 @@
     */
    public Iterable<URL> getResources(String name);
    
+   /**
+    * Gets a resource as an InputStream by name
+    * 
+    * @param name The name of the resource
+    * @return An InputStream of the resource
+    */
+   public InputStream getResourceAsStream(String name);
+   
+   /**
+    * Load a ResourceBundle for the given bundle name. The
+    * locale is detected automatically from the current Locale
+    * bean instance.
+    * 
+    * @param bundleName The name of the resource bundle to load.
+    * @return A ResourceBundle for the bundle name
+    */
+   public ResourceBundle loadBundle(String bundleName);
 }

Modified: modules/trunk/resources/src/main/java/org/jboss/seam/resources/ResourceLoaderProducer.java
===================================================================
--- modules/trunk/resources/src/main/java/org/jboss/seam/resources/ResourceLoaderProducer.java	2009-05-28 19:09:19 UTC (rev 11025)
+++ modules/trunk/resources/src/main/java/org/jboss/seam/resources/ResourceLoaderProducer.java	2009-05-28 19:13:06 UTC (rev 11026)
@@ -32,5 +32,4 @@
    {
       return super.selectImplementation();
    }
-   
 }




More information about the seam-commits mailing list