EMPIREDB-310
Overcome ParamterMap limitations (see Jira)
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java
index d26bd72..50dad0e 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java
@@ -133,7 +133,7 @@
return context.getExternalContext().getRequestParameterMap().get(param);
}
- public static Object getRequestParam(final String key)
+ public static String getRequestParam(final String key)
{
FacesContext fc = getContext();
return getRequestParam(fc, key);
@@ -212,17 +212,54 @@
}
/* Parameter-map */
- public static final String PARAMETER_MAP_ATTRIBUTE = ParameterMap.class.getSimpleName();
+ public static final String PARAMETER_MAP_ATTRIBUTE = "PARAMETER_MAP";
+
+ public static final String PARAMETER_MAP_CLASS_ATTRIBUTE = "PARAMETER_MAP_CLASS";
+
+ public static void setParameterMapClass(final FacesContext fc, Class<? extends ParameterMap>clazz)
+ {
+ Map<String, Object> am = fc.getExternalContext().getApplicationMap();
+ am.put(PARAMETER_MAP_CLASS_ATTRIBUTE, clazz);
+ }
public static ParameterMap getParameterMap(final FacesContext fc)
{
Map<String, Object> sm = fc.getExternalContext().getSessionMap();
- Object pm = sm.get(PARAMETER_MAP_ATTRIBUTE);
+ ParameterMap pm = (ParameterMap)sm.get(PARAMETER_MAP_ATTRIBUTE);
if (pm==null)
- { pm = new ParameterMap();
+ { try
+ { // Create Paramter Map
+ Map<String, Object> am = fc.getExternalContext().getApplicationMap();
+ Object pmClass = am.get(PARAMETER_MAP_CLASS_ATTRIBUTE);
+ if (pmClass instanceof Class<?>) {
+ // ParamterMapClass provided as Object
+ pm = (ParameterMap)((Class<?>)pmClass).newInstance();
+ }
+ else if (pmClass instanceof String) {
+ // ParamterMapClass provided as String
+ pm = (ParameterMap)Class.forName((String)pmClass).newInstance();
+ }
+ else {
+ // not provided, use default
+ pm = new ParameterMap();
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new InternalException(e);
+ }
+ catch (InstantiationException e)
+ {
+ throw new InternalException(e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new InternalException(e);
+ }
+ // put on session
sm.put(PARAMETER_MAP_ATTRIBUTE, pm);
}
- return (ParameterMap)pm;
+ return pm;
}
public static ParameterMap getParameterMap()
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/BeanListPageElement.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/BeanListPageElement.java
index 893fadc..8da9047 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/BeanListPageElement.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/BeanListPageElement.java
@@ -545,7 +545,7 @@
Set<Object[]> items = new HashSet<Object[]>(selectedItems.size());
for (String idParam : selectedItems)
{
- Object[] key = getParameterMap().get(rowset, idParam);
+ Object[] key = getParameterMap().getKey(rowset, idParam);
if (key == null)
{
log.warn("Object does not exist in ParameterMap!");
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java
index 25af54b..47a4bd4 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java
@@ -397,13 +397,13 @@
public Object[] getKeyFromParam(DBRowSet rowset, String idParam)
{
FacesContext fc = FacesUtils.getContext();
- return FacesUtils.getParameterMap(fc).get(rowset, idParam);
+ return FacesUtils.getParameterMap(fc).getKey(rowset, idParam);
}
public Object[] getKeyFromParam(PageDefinition page, DBRowSet rowset, String idParam)
{
FacesContext fc = FacesUtils.getContext();
- return FacesUtils.getParameterMap(fc).get(page, rowset, idParam);
+ return FacesUtils.getParameterMap(fc).getKey(page, rowset, idParam);
}
public String getIdParamForKey(DBRowSet rowset, Object[] key)
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ParameterMap.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ParameterMap.java
index 88b4024..31aace7 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ParameterMap.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ParameterMap.java
@@ -62,6 +62,10 @@
}
private final byte[] salt;
+
+ protected Hashtable<String, String> codeMap = new Hashtable<String, String>();
+
+ protected final Hashtable<String, Hashtable<String, Object>> typeMap = new Hashtable<String, Hashtable<String, Object>>();
public ParameterMap()
{
@@ -100,8 +104,6 @@
return hash.toString();
}
- private Hashtable<String, String> codeMap = new Hashtable<String, String>();
-
public String encodeStringWithCache(String valueAsString)
{
String code = codeMap.get(valueAsString);
@@ -110,61 +112,104 @@
code = encodeString(valueAsString);
codeMap.put(valueAsString, code);
}
- /*
- else
- { // Trace
- if (log.isTraceEnabled())
- log.trace("Using already generated code {} for value {}.", code, valueAsString);
- }
- */
return code;
}
-
- private final Hashtable<String, Hashtable<String, Object>> typeMap = new Hashtable<String, Hashtable<String, Object>>();
-
- private void putValue(String typeName, String key, Object value)
+
+ /**
+ * gets a unique name for a given rowset
+ * @param rowset
+ * @return a unique name for the given rowset
+ */
+ protected String getRowSetTypeName(DBRowSet rowset)
{
+ /*
+ * alternatively use:
+ * rowset.getName();
+ * or
+ * rowset.getFullName();
+ */
+ return rowset.getClass().getName();
+ }
+
+ /**
+ * puts an object into the parameter map
+ * @param typeName
+ * @param id
+ * @param value
+ */
+ protected void putValue(String typeName, String encodedId, Object item)
+ { // put in Table
+ if (encodedId==null)
+ {
+ throw new InvalidArgumentException("encodedId", encodedId);
+ }
Hashtable<String, Object> map = typeMap.get(typeName);
if (map==null)
{ map = new Hashtable<String, Object>(1);
typeMap.put(typeName, map);
}
- if (key==null || value==null)
- log.warn("Key or value is null.");
- map.put(key, value);
+ map.put(encodedId, item);
+ }
+
+ /**
+ * encodes the objectKey and stores the item in the parameter map
+ * @param typeName
+ * @param id
+ * @param value
+ */
+ protected String encodeAndStore(String typeName, String objectKey, Object item, boolean useCache)
+ { // Generate the id
+ String encodedId = (useCache ? encodeStringWithCache(objectKey) : encodeString(objectKey));
+ // store
+ putValue(typeName, encodedId, item);
+ // return id
+ return encodedId;
}
public String put(String type, String key, boolean useCache)
{
// Generate id and put in map
- String id = (useCache ? encodeStringWithCache(key) : encodeString(key));
- putValue(type, id, key);
- return id;
+ return encodeAndStore(type, key, key, useCache);
}
- public String put(Class<? extends Object> c, Object[] key)
+ /**
+ * Puts an object into the paramter map that implements the ParameterObject interface
+ * @param paramObject
+ * @return
+ */
+ public String put(ParameterObject paramObject)
{
+ String objectKey;
+ // check param
+ if (paramObject==null || StringUtils.isEmpty((objectKey=paramObject.getObjectKey())))
+ throw new InvalidArgumentException("paramObject", paramObject);
// Generate id and put in map
- String ref = StringUtils.valueOf(key);
- String id = encodeString(ref);
- String type = c.getSimpleName();
- putValue(type, id, key);
- return id;
+ String type = paramObject.getClass().getName();
+ return encodeAndStore(type, objectKey, paramObject, false);
}
public String put(DBRowSet rowset, Object[] key)
{
// Generate id and put in map
- String ref = StringUtils.valueOf(key);
- String id = encodeString(ref);
- String type = rowset.getClass().getSimpleName();
- putValue(type, id, key);
- return id;
+ String rowKey = StringUtils.valueOf(key);
+ String type = getRowSetTypeName(rowset);
+ return encodeAndStore(type, rowKey, key, false);
}
+
+ /*
+ * do we really need this?
+ *
+ public String put(Class<? extends Object> c, Object[] key)
+ {
+ // Generate id and put in map
+ String ref = StringUtils.valueOf(key);
+ String type = c.getName();
+ return encodeAndStore(type, ref, key, false);
+ }
+ */
/**
* Generates an idParam which is only valid for the given page.
- *
* @param targetPage
* @param rowset
* @param key
@@ -172,54 +217,85 @@
*/
public String put(PageDefinition targetPage, DBRowSet rowset, Object[] key) {
// Generate id and put in map
- String ref = targetPage.getPageBeanName() + "/" + StringUtils.valueOf(key);
- String idParam = encodeString(ref);
- String type = targetPage.getPageBeanName() + "$" + rowset.getClass().getSimpleName();
- putValue(type, idParam, key);
- return idParam;
+ String ref = StringUtils.valueOf(key);
+ String type = targetPage.getPageBeanName() + "$" + getRowSetTypeName(rowset);
+ return encodeAndStore(type, ref, key, false);
}
+ /**
+ * Gets an object from the parameter map for a given type and id
+ * @param type the object type (typically the class name)
+ * @param id the encoded idParam
+ * @return the object
+ */
public Object get(String type, String id)
{
Hashtable<String, Object> map = typeMap.get(type);
return (map!=null ? map.get(id) : null);
}
- public Object[] get(Class<? extends Object> c, String id)
+ public void clear(String type)
{
- String type = c.getSimpleName();
- Hashtable<String, Object> map = typeMap.get(type);
- return (map!=null ? ((Object[])map.get(id)) : null);
- }
-
- public Object[] get(DBRowSet rowset, String id)
- {
- String type = rowset.getClass().getSimpleName();
- Hashtable<String, Object> map = typeMap.get(type);
- return (map!=null ? ((Object[])map.get(id)) : null);
- }
-
- public Object[] get(PageDefinition page, DBRowSet rowset, String id)
- {
- String type = page.getPageBeanName() + "$" + rowset.getClass().getSimpleName();
- Hashtable<String, Object> map = typeMap.get(type);
- return (map!=null ? ((Object[])map.get(id)) : null);
- }
-
- public void clear(Class<? extends Object> c)
- {
- String type = c.getSimpleName();
Hashtable<String, Object> map = typeMap.get(type);
if (map!=null)
map.clear();
}
+ /**
+ * Puts an object into the paramter map that implements the ParameterObject interface
+ * @param paramType
+ * @param id
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public <T extends ParameterObject> T get(Class<T> paramType, String id)
+ {
+ String type = paramType.getName();
+ Hashtable<String, Object> map = typeMap.get(type);
+ return (T)(map!=null ? map.get(id) : null);
+ }
+
+ public void clear(Class<? extends ParameterObject> paramType)
+ {
+ String type = paramType.getName();
+ clear(type);
+ }
+
+ /*
+ * do we really need this?
+ *
+ public Object[] getKey(Class<? extends Object> c, String id)
+ {
+ String type = c.getName();
+ Hashtable<String, Object> map = typeMap.get(type);
+ return (map!=null ? ((Object[])map.get(id)) : null);
+ }
+ */
+
+ public Object[] getKey(DBRowSet rowset, String id)
+ {
+ String type = getRowSetTypeName(rowset);
+ Hashtable<String, Object> map = typeMap.get(type);
+ return (map!=null ? ((Object[])map.get(id)) : null);
+ }
+
public void clear(DBRowSet rowset)
{
- String type = rowset.getClass().getSimpleName();
- Hashtable<String, Object> map = typeMap.get(type);
- if (map!=null)
- map.clear();
+ String type = getRowSetTypeName(rowset);
+ clear(type);
}
+ /**
+ * returns an record key for a given page
+ * @param page
+ * @param rowset
+ * @param id
+ * @return
+ */
+ public Object[] getKey(PageDefinition page, DBRowSet rowset, String id)
+ {
+ String type = page.getPageBeanName() + "$" + getRowSetTypeName(rowset);
+ Hashtable<String, Object> map = typeMap.get(type);
+ return (map!=null ? ((Object[])map.get(id)) : null);
+ }
}
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ParameterObject.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ParameterObject.java
new file mode 100644
index 0000000..8108ef5
--- /dev/null
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ParameterObject.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.jsf2.utils;
+
+/**
+ * ParameterObject
+ * This interface is used to store objects in the session parameter map
+ * The object must provide a unique instance key as a String
+ * @author doebele
+ */
+public interface ParameterObject
+{
+ /**
+ * provides the unique instance key for this object
+ * @return the unique key
+ */
+ String getObjectKey();
+}