Author: mbenson
Date: Thu Feb 4 19:48:07 2010
New Revision: 906622
URL: http://svn.apache.org/viewvc?rev=906622&view=rev
Log:
use an object pool instead of a ThreadLocal to ensure that different
EntityTreeParsers are used concurrently
Modified:
commons/sandbox/flatfile/trunk/pom.xml
commons/sandbox/flatfile/trunk/src/main/java/org/apache/commons/flatfile/dsl/ParserEntityFactory.java
Modified: commons/sandbox/flatfile/trunk/pom.xml
URL:
http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/pom.xml?rev=906622&r1=906621&r2=906622&view=diff
==============================================================================
--- commons/sandbox/flatfile/trunk/pom.xml (original)
+++ commons/sandbox/flatfile/trunk/pom.xml Thu Feb 4 19:48:07 2010
@@ -59,6 +59,12 @@
<version>3.2.1</version>
</dependency>
<dependency>
+ <groupId>commons-pool</groupId>
+ <artifactId>commons-pool</artifactId>
+ <version>1.5.4</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
<groupId>net.sf.morph</groupId>
<artifactId>morph</artifactId>
<version>1.1.1</version>
Modified:
commons/sandbox/flatfile/trunk/src/main/java/org/apache/commons/flatfile/dsl/ParserEntityFactory.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/main/java/org/apache/commons/flatfile/dsl/ParserEntityFactory.java?rev=906622&r1=906621&r2=906622&view=diff
==============================================================================
---
commons/sandbox/flatfile/trunk/src/main/java/org/apache/commons/flatfile/dsl/ParserEntityFactory.java
(original)
+++
commons/sandbox/flatfile/trunk/src/main/java/org/apache/commons/flatfile/dsl/ParserEntityFactory.java
Thu Feb 4 19:48:07 2010
@@ -24,10 +24,14 @@
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.commons.pool.BasePoolableObjectFactory;
+import org.apache.commons.pool.ObjectPool;
+import org.apache.commons.pool.impl.StackObjectPool;
import antlr.TokenBuffer;
import antlr.collections.AST;
+import org.apache.commons.collections.Transformer;
import org.apache.commons.flatfile.DynamicField;
import org.apache.commons.flatfile.Entity;
import org.apache.commons.flatfile.EntityFactory;
@@ -66,7 +70,12 @@
Entity getPrototype() {
synchronized (this) {
if (prototype == null) {
- prototype = getTreeParser().createEntity(definition);
+ prototype = (Entity) doWithPooledTreeParser(new
Transformer() {
+
+ public Object transform(Object arg0) {
+ return ((EntityTreeParser)
arg0).createEntity(definition);
+ }
+ });
}
}
return prototype;
@@ -74,21 +83,21 @@
}
private EntityNameStrategy entityNameStrategy;
+ private Map<String, EntityHolder> entityMap;
+ private Map<String, Map<String, ? extends Object>> defaultOptionMaps = new
HashMap<String, Map<String, ? extends Object>>();
+ private boolean checked;
+ private InputStream[] sources;
+ private EntityFactory parent;
+
+ private final ObjectPool treeParserPool = new StackObjectPool(new
BasePoolableObjectFactory() {
- private ThreadLocal<EntityTreeParser> treeParser = new
ThreadLocal<EntityTreeParser>() {
- protected EntityTreeParser initialValue() {
+ @Override
+ public Object makeObject() throws Exception {
EntityTreeParser result = new EntityTreeParser();
result.setEntityFactory(ParserEntityFactory.this);
return result;
}
- };
-
- private Map<String, EntityHolder> entityMap;
- private Map<String, Map<String, ? extends Object>> defaultOptionMaps
- = new HashMap<String, Map<String, ? extends Object>>();
- private boolean checked;
- private InputStream[] sources;
- private EntityFactory parent;
+ }, 1);
/**
* Create a new ParserEntityFactory.
@@ -260,14 +269,6 @@
}
/**
- * Get this thread's {...@link EntityTreeParser}
- * @return {...@link EntityTreeParser}
- */
- private EntityTreeParser getTreeParser() {
- return treeParser.get();
- }
-
- /**
* Return our entity map, initializing if necessary.
* @return Map<String, EntityProxy> - value may be an EntityDefinition or
an Entity.
*/
@@ -276,7 +277,7 @@
entityMap = new HashMap<String, EntityHolder>();
try {
EntityParser p = null;
- ArrayList<AST> trees = new ArrayList<AST>();
+ final ArrayList<AST> trees = new ArrayList<AST>();
InputStream[] is = getSources();
for (int i = 0; i < is.length; i++) {
TokenBuffer tb = new TokenBuffer(new EntityLexer(is[i]));
@@ -288,9 +289,21 @@
p.parse();
trees.add(p.getAST());
}
- for (AST ast : trees) {
- getTreeParser().load(ast);
- }
+ doWithPooledTreeParser(new Transformer() {
+
+ public Object transform(Object arg0) {
+ for (AST ast : trees) {
+ try {
+ ((EntityTreeParser) arg0).load(ast);
+ } catch (Exception e) {
+ throw e instanceof RuntimeException ?
(RuntimeException) e
+ : new RuntimeException(e);
+ }
+ }
+ // TODO Auto-generated method stub
+ return null;
+ }
+ });
} catch (Exception e) {
throw e instanceof RuntimeException ? (RuntimeException) e
: new RuntimeException(e);
@@ -299,4 +312,19 @@
return entityMap;
}
+ private Object doWithPooledTreeParser(Transformer t) {
+ EntityTreeParser entityTreeParser = null;
+ try {
+ entityTreeParser = (EntityTreeParser)
treeParserPool.borrowObject();
+ } catch (Exception e) {
+ throw e instanceof RuntimeException ? (RuntimeException) e : new
RuntimeException(e);
+ }
+ Object result = t.transform(entityTreeParser);
+ try {
+ treeParserPool.returnObject(entityTreeParser);
+ } catch (Exception e) {
+ LOG.error("Error returning EntityTreeParser to pool", e);
+ }
+ return result;
+ }
}