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
-@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
-@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
+@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
+@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
+@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
+@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
- */
-@Artifact(addCurrentPackage = false)
-(a)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
- */
-@Artifact(addCurrentPackage = false)
-@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
- */
-@Artifact(addCurrentPackage = false)
-@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
+ */
+@Artifact(addCurrentPackage = false)
+(a)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
+ */
+@Artifact(addCurrentPackage = false)
+@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;
+
+@Artifact(addCurrentPackage = false)
+(a)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
+ */
+@Artifact(addCurrentPackage = false)
+@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
+ */
+@Target( { TYPE, METHOD, PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+@BindingType
+@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
+@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
-@Target( { TYPE, METHOD, PARAMETER, FIELD })
-@Retention(RUNTIME)
-@Documented
-@BindingType
-@Inherited
-@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;
+
+@Artifact
+(a)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)
-(a)Classes({Interpolator.class, Expressions.class, ExpressionsProducer.class,
LocaleProducer.class})
+(a)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)
-(a)Classes(LocaleProducer.class)
+(a)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
+@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();
}
-
}