Better concurrency
git-svn-id: https://svn.apache.org/repos/asf/turbine/core/trunk@1885116 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/java/org/apache/turbine/services/rundata/TurbineRunDataService.java b/src/java/org/apache/turbine/services/rundata/TurbineRunDataService.java
index 4331d9f..e09ea77 100644
--- a/src/java/org/apache/turbine/services/rundata/TurbineRunDataService.java
+++ b/src/java/org/apache/turbine/services/rundata/TurbineRunDataService.java
@@ -19,10 +19,10 @@
* under the License.
*/
-import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
-import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
@@ -44,6 +44,7 @@
import org.apache.turbine.util.RunData;
import org.apache.turbine.util.ServerData;
import org.apache.turbine.util.TurbineException;
+import org.apache.turbine.util.TurbineRuntimeException;
/**
* The RunData Service provides the implementations for RunData and
@@ -74,10 +75,10 @@
DefaultCookieParser.class.getName();
/** The map of configurations. */
- private final Map<String, Object> configurations = new HashMap<String, Object>();
+ private final ConcurrentMap<String, Object> configurations = new ConcurrentHashMap<>();
/** A class cache. */
- private final Map<String, Class<?>> classCache = new HashMap<String, Class<?>>();
+ private final ConcurrentMap<String, Class<?>> classCache = new ConcurrentHashMap<>();
/** Private reference to the pool service for object recycling */
private PoolService pool = null;
@@ -127,11 +128,12 @@
{
key = i.next();
value = conf.getString(key);
- for (int j = 0; j < plist.length; j++)
+ int j = 0;
+ for (String plistKey : plist)
{
- if (key.endsWith(plist[j]) && key.length() > plist[j].length() + 1)
+ if (key.endsWith(plistKey) && key.length() > plistKey.length() + 1)
{
- key = key.substring(0, key.length() - plist[j].length() - 1);
+ key = key.substring(0, key.length() - plistKey.length() - 1);
config = (String[]) configurations.get(key);
if (config == null)
{
@@ -141,6 +143,7 @@
config[j] = value;
break;
}
+ j++;
}
}
}
@@ -236,26 +239,9 @@
TurbineRunData data;
try
{
- Class<?> runDataClazz = classCache.get(cfg[0]);
- if (runDataClazz == null)
- {
- runDataClazz = Class.forName(cfg[0]);
- classCache.put(cfg[0], runDataClazz);
- }
-
- Class<?> parameterParserClazz = classCache.get(cfg[1]);
- if (parameterParserClazz == null)
- {
- parameterParserClazz = Class.forName(cfg[1]);
- classCache.put(cfg[1], parameterParserClazz);
- }
-
- Class<?> cookieParserClazz = classCache.get(cfg[2]);
- if (cookieParserClazz == null)
- {
- cookieParserClazz = Class.forName(cfg[2]);
- classCache.put(cfg[2], cookieParserClazz);
- }
+ Class<?> runDataClazz = classCache.computeIfAbsent(cfg[0], className -> classForName(className));
+ Class<?> parameterParserClazz = classCache.computeIfAbsent(cfg[1], className -> classForName(className));
+ Class<?> cookieParserClazz = classCache.computeIfAbsent(cfg[2], className -> classForName(className));
data = (TurbineRunData) pool.getInstance(runDataClazz);
@SuppressWarnings("unchecked") // ok
@@ -281,7 +267,7 @@
{
throw new TurbineException("RunData configuration '" + key + "' is illegal caused a pool exception", pe);
}
- catch (ClassNotFoundException | ClassCastException | InstantiationException x)
+ catch (TurbineRuntimeException | ClassCastException | InstantiationException x)
{
throw new TurbineException("RunData configuration '" + key + "' is illegal", x);
}
@@ -321,4 +307,17 @@
return false;
}
}
+
+ @SuppressWarnings("unchecked") // ok
+ private <T> Class<T> classForName(String className) throws TurbineRuntimeException
+ {
+ try
+ {
+ return (Class<T>) Class.forName(className);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new TurbineRuntimeException("Could not load class " + className, e);
+ }
+ }
}