Author: ekoneil
Date: Wed Jul 21 06:50:54 2004
New Revision: 23122
Modified:
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/AbstractScriptableMap.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/BundleMap.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ScriptablePageInput.java
incubator/beehive/trunk/netui/test/src/junitTests/org/apache/beehive/netui/test/script/BundleScriptTest.java
incubator/beehive/trunk/netui/test/src/junitTests/org/apache/beehive/netui/test/script/el/NetUIELBundleScriptTest.java
Log:
Provide implementations of entrySet in the data binding related maps below.
These are used to provide access to resource bundles and page inputs from
expression languages.
In general, the implementations are optimized for read in which cases, the
entrySet is not created eagerly and is created only when asked for. Subclasses
of AbstractScriptableMap generally provide their own implementations of
Map.get(Object).
BB: self
DRT: NetUI (junit + server) pass
CR: Daryl
Modified:
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/AbstractScriptableMap.java
==============================================================================
---
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/AbstractScriptableMap.java
(original)
+++
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/AbstractScriptableMap.java
Wed Jul 21 06:50:54 2004
@@ -19,7 +19,12 @@
package org.apache.beehive.netui.script.common;
// java imports
+import org.apache.beehive.netui.util.iterator.IteratorFactory;
+
import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Iterator;
import java.util.Map;
// internal imports
@@ -27,73 +32,107 @@
// external imports
/**
- *
+ * Base [EMAIL PROTECTED] java.util.Map} implementation that can be used by
+ * clients that need to expose implicit objects to an expression
+ * language through a Map. This Map implementation is read-only.
*/
public abstract class AbstractScriptableMap
extends AbstractMap
{
- public AbstractScriptableMap()
- {
- }
-
- public void clear()
- {
- throw new UnsupportedOperationException("The clear method is not
supported");
- }
-
- public Object put(Object key, Object value)
- {
- throw new UnsupportedOperationException("The put method is not
supported");
- }
+ public AbstractScriptableMap() {}
- public void putAll(Map map)
+ /**
+ * Default implementation of a [EMAIL PROTECTED] java.util.Set} that can
be returned by the
+ * entrySet method of [EMAIL PROTECTED] java.util.Map}. This
implementation simply takes an
+ * array of entries and implements iterator() and size().
+ */
+ class EntrySet
+ extends AbstractSet
{
- throw new UnsupportedOperationException("The putAll method is not
supported");
- }
+ private Entry[] _entries = null;
- public Object remove(Object key)
- {
- throw new UnsupportedOperationException("The key method is not
supported");
+ public EntrySet(Entry[] entries)
+ {
+ _entries = entries;
+ }
+ public Iterator iterator()
+ {
+ return IteratorFactory.createIterator(_entries);
+ }
+
+ public int size()
+ {
+ return (_entries != null ? _entries.length : 0);
+ }
+
+ public boolean add(Object object) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean addAll(Collection coll) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean remove(Object object) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean removeAll(Collection coll) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean retainAll(Collection coll) {
+ throw new UnsupportedOperationException();
+ }
}
- public static class Entry
+ /**
+ * Default implementation of [EMAIL PROTECTED] java.util.Map.Entry} that
handles
+ * key / value pairs in a very basic way. This is meant as a convenience
+ * to subclasses that need to provide an entrySet() to satisfy the
+ * [EMAIL PROTECTED] java.util.AbstractMap} contract.
+ */
+ class Entry
implements Map.Entry
{
private final Object _key;
private final Object _value;
-
+
Entry(Object key, Object value)
{
_key = key;
_value = value;
}
-
+
public Object getKey() {return _key;}
public Object getValue() {return _value;}
-
+
public Object setValue(Object value)
{
- throw new UnsupportedOperationException("The setValue method is
not supported");
+ throw new UnsupportedOperationException();
}
-
+
public int hashCode()
{
return ((_key == null ? 0 : _key.hashCode()) ^ (_value == null ? 0
: _value.hashCode()));
}
-
+
public boolean equals(Object obj)
{
if(obj == null || !(obj instanceof Map.Entry))
return false;
-
+
Map.Entry entry = (Map.Entry)obj;
Object key = entry.getKey();
Object value = entry.getValue();
- if((key == null || (key != null && key.equals(_key)))
- &&
+ if((key == null || (key != null && key.equals(_key))) &&
(value == null || (value != null && value.equals(_value))))
return true;
-
+
return false;
}
}
Modified:
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/BundleMap.java
==============================================================================
---
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/BundleMap.java
(original)
+++
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/BundleMap.java
Wed Jul 21 06:50:54 2004
@@ -19,9 +19,11 @@
package org.apache.beehive.netui.script.common;
// java imports
+import java.util.ArrayList;
+import java.util.Set;
import java.util.Iterator;
import java.util.Locale;
-import java.util.Set;
+import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@@ -38,7 +40,14 @@
import org.apache.struts.util.MessageResources;
/**
+ * Provide a [EMAIL PROTECTED] java.util.Map} of [EMAIL PROTECTED]
ScriptableBundle} objects that can expose
+ * various implementations of [EMAIL PROTECTED] BundleContext.BundleNode} to
expression languages.
+ *
+ * This [EMAIL PROTECTED] java.util.Map} implementation is optimized for read
as the entrySet()
+ * is created lazily. In addition, the entrySet does not contain all possible
ScriptableBundle
+ * objects as named "message-resources" bundles are discovered at runtime and
requested by name.
*
+ * todo: need to implement Serializable here as this ends up in the request
*/
public class BundleMap
extends AbstractScriptableMap
@@ -103,7 +112,29 @@
public Set entrySet()
{
- throw new UnsupportedOperationException("The entrySet method is not
supported");
+ ArrayList entries = new ArrayList();
+
+ // add BundleNode objects that have been explicitly declared
+ if(_bundleContext != null)
+ {
+ Iterator iterator = _bundleContext.getBundleNames();
+ while(iterator.hasNext())
+ {
+ String name = (String)iterator.next();
+ BundleNode node = _bundleContext.getBundle(name);
+ entries.add(new Entry(name, node));
+ }
+ }
+
+ // add the default JPF bundle if one exists
+ MessageResources resources = getDefaultStrutsModuleBundle();
+ if(resources != null)
+ entries.add(new Entry(BundleContext.DEFAULT_STRUTS_BUNDLE_NAME,
+
BundleContext.createBundleNode(BundleContext.DEFAULT_STRUTS_BUNDLE_NAME,
resources, retrieveUserLocale())));
+
+ // todo: the named "message-resource" bundles aren't supported here
yet; need a way from the JPF runtime to look them up
+
+ return new EntrySet((Entry[])entries.toArray(new Entry[]{}));
}
private Object createScriptableBundle(String name)
@@ -134,7 +165,7 @@
else if(_application.getAttribute(name) != null)
{
MessageResources resources = getNamedStrutsModuleBundle(name);
-
+
if(resources != null)
{
BundleNode bundleNode = BundleContext.createBundleNode(name,
resources, retrieveUserLocale());
@@ -144,8 +175,8 @@
String bundleList = createBundleList();
String strutsBundleList = createStrutsBundleList();
-
- String msg = "The bundle named \"" + name + "\" was not found in the
list of registered bundles with names " +
+
+ String msg = "The bundle named \"" + name + "\" was not found in the
list of registered bundles with names " +
bundleList + " or implicit bundle names " + strutsBundleList + ".";
if(_logger.isErrorEnabled()) _logger.error(msg);
@@ -263,8 +294,13 @@
return strutsNameList.toString();
}
- /*
- *
+ /**
+ * Provide a [EMAIL PROTECTED] java.util.Map} implementation that exposes a
+ * [EMAIL PROTECTED]
org.apache.beehive.netui.script.common.BundleContext.BundleNode} object
+ * to an expression language as a Map. Access to the values in the map is
by
+ * key and depends on the implementation of the BundleNode.
+ *
+ * Access is read optimized and the complete entrySet() is only
constructed when needed.
*/
public class ScriptableBundle
extends AbstractScriptableMap
@@ -283,7 +319,15 @@
public Set entrySet()
{
- throw new UnsupportedOperationException("The entrySet method is
not supported");
+ ArrayList list = new ArrayList();
+ Enumeration enumeration = _bundle.getKeys();
+ while(enumeration.hasMoreElements())
+ {
+ String key = (String)enumeration.nextElement();
+ String msg = _bundle.getString(key);
+ list.add(new Entry(key, msg));
+ }
+ return new EntrySet((Entry[])list.toArray(new Entry[] {}));
}
public Object get(Object name)
Modified:
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ScriptablePageInput.java
==============================================================================
---
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ScriptablePageInput.java
(original)
+++
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ScriptablePageInput.java
Wed Jul 21 06:50:54 2004
@@ -19,7 +19,8 @@
package org.apache.beehive.netui.script.common;
// java imports
-import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -34,7 +35,12 @@
// external imports
/**
- * @todo: need to finish this implementation
+ * Provide a [EMAIL PROTECTED] java.util.Map} object that exposes a set of
page inputs to
+ * expression language clients. Access to these page inputs is based on the
+ * name of the page input.
+ *
+ * Access is optimized for read in that the "get" method is fast. The
entrySet()
+ * method is only used if needed, which is generally to toString the Map.
*/
public class ScriptablePageInput
extends AbstractScriptableMap
@@ -42,6 +48,7 @@
private static final Logger _logger =
Logger.getInstance(ScriptablePageInput.class);
private HttpServletRequest _request = null;
+ private Set _entrySet = null;
public ScriptablePageInput(ServletRequest request)
{
@@ -58,10 +65,35 @@
return PageFlowUtils.getActionOutput((String)name, _request);
}
-
+
+ /**
+ * Create a [EMAIL PROTECTED] java.util.Set} of page input entries. This
implementation
+ * assumes that the page input set does not change, which is acceptable for
+ * JSP clients as the page inputs have been specified when the JSP starts
+ * to render.
+ * @return
+ */
public Set entrySet()
{
- throw new UnsupportedOperationException("Operation entrySet not
supported on the PageInput Map");
+ if(_entrySet == null)
+ {
+ Map piMap = InternalUtils.getActionOutputMap(_request, false);
+ ArrayList list = new ArrayList();
+ if(piMap != null)
+ {
+ Iterator iterator = piMap.keySet().iterator();
+ while(iterator.hasNext())
+ {
+ Object name = iterator.next();
+ Object value = piMap.get(name);
+ list.add(new Entry(name, value));
+ }
+ }
+
+ _entrySet = new EntrySet((Entry[])list.toArray(new Entry[]{}));
+ }
+
+ return _entrySet;
}
public boolean equals(Object obj)
Modified:
incubator/beehive/trunk/netui/test/src/junitTests/org/apache/beehive/netui/test/script/BundleScriptTest.java
==============================================================================
---
incubator/beehive/trunk/netui/test/src/junitTests/org/apache/beehive/netui/test/script/BundleScriptTest.java
(original)
+++
incubator/beehive/trunk/netui/test/src/junitTests/org/apache/beehive/netui/test/script/BundleScriptTest.java
Wed Jul 21 06:50:54 2004
@@ -82,6 +82,32 @@
assertEquals("This message is never localized", val);
}
+ /**
+ * Simple test to make sure that BundleMap.toString() doesn't throw
exceptions and generally works.
+ * @throws Exception
+ */
+ public void testToString()
+ throws Exception
+ {
+ BundleContext bc = createBundleContext();
+ BundleMap bundleMap = new
BundleMap((HttpServletRequest)_fauxPageContext.getRequest(),
+
_fauxPageContext.getServletContext(),
+ bc);
+ // toString an empty map
+ System.out.println("budleMap.toString(): " + bundleMap.toString());
+
+ _fauxPageContext.setAttribute("bundle", bundleMap);
+
+ bc.addBundle("bundle1",
"org/apache/beehive/netui/test/databinding/testdata/bundle1");
+ bc.addBundle("bundle2",
"org/apache/beehive/netui/test/databinding/testdata/bundle2");
+
+ String val = (String)evaluateExpression("{bundle.bundle1.simpleKey}",
_fauxPageContext);
+ assertEquals("This is a simple message.", val);
+
+ // toString a BundleMap that has bundles
+ System.out.println("bundleMap.toString(): " + bundleMap.toString());
+ }
+
private BundleContext createBundleContext()
throws Exception
{
Modified:
incubator/beehive/trunk/netui/test/src/junitTests/org/apache/beehive/netui/test/script/el/NetUIELBundleScriptTest.java
==============================================================================
---
incubator/beehive/trunk/netui/test/src/junitTests/org/apache/beehive/netui/test/script/el/NetUIELBundleScriptTest.java
(original)
+++
incubator/beehive/trunk/netui/test/src/junitTests/org/apache/beehive/netui/test/script/el/NetUIELBundleScriptTest.java
Wed Jul 21 06:50:54 2004
@@ -51,6 +51,7 @@
TestSuite suite = new TestSuite();
suite.addTest(new NetUIELBundleScriptTest("testSimple"));
suite.addTest(new NetUIELBundleScriptTest("testLocaleSupport"));
+ suite.addTest(new NetUIELBundleScriptTest("testToString"));
return suite;
}