Author: scabanovich
Date: 2008-10-29 08:57:57 -0400 (Wed, 29 Oct 2008)
New Revision: 11283
Modified:
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/model/ELModel.java
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/ELParser.java
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/ELParserUtil.java
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/Tokenizer.java
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/TokenizerFactory.java
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/resolver/Var.java
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/internal/core/model/ELModelImpl.java
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/internal/core/parser/ELParserImpl.java
Log:
Pool for EL parsers implemented.
Modified:
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/model/ELModel.java
===================================================================
---
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/model/ELModel.java 2008-10-29
12:54:37 UTC (rev 11282)
+++
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/model/ELModel.java 2008-10-29
12:57:57 UTC (rev 11283)
@@ -12,6 +12,8 @@
import java.util.List;
+import org.jboss.tools.common.el.core.parser.SyntaxError;
+
/**
* ELModel object is the result of EL parsing that includes
* all found instances of EL in the source string.
@@ -25,6 +27,8 @@
public List<ELInstance> getInstances();
+ public List<SyntaxError> getSyntaxErrors();
+
public void shift(int delta);
}
Modified:
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/ELParser.java
===================================================================
---
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/ELParser.java 2008-10-29
12:54:37 UTC (rev 11282)
+++
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/ELParser.java 2008-10-29
12:57:57 UTC (rev 11283)
@@ -25,6 +25,4 @@
public ELModel parse(String source, int start, int length);
- public List<SyntaxError> getSyntaxErrors();
-
}
Modified:
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/ELParserUtil.java
===================================================================
---
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/ELParserUtil.java 2008-10-29
12:54:37 UTC (rev 11282)
+++
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/ELParserUtil.java 2008-10-29
12:57:57 UTC (rev 11283)
@@ -11,6 +11,7 @@
package org.jboss.tools.common.el.core.parser;
import java.util.List;
+import java.util.Stack;
import org.jboss.tools.common.el.core.model.ELModel;
import org.jboss.tools.common.el.internal.core.model.ELModelImpl;
@@ -23,53 +24,104 @@
*/
public class ELParserUtil {
+ private static ELParserFactory DEFAULT_FACTORY = new DefaultFactory() {
+ public ELParser newParser() {
+ return new DefaultParser() {
+ protected Tokenizer createTokenizer() {
+ return TokenizerFactory.createDefaultTokenizer();
+ }
+ public void dispose() {
+ super.dispose();
+ release(this);
+ }
+ };
+ }
+ };
+
public static ELParserFactory getDefaultFactory() {
- return new ELParserFactory() {
- public ELParser createParser() {
- return new DefaultParser() {
- protected Tokenizer createTokenizer() {
- return TokenizerFactory.createDefaultTokenizer();
- }
- };
- }
- };
+ return DEFAULT_FACTORY;
}
+ private static ELParserFactory JBOSS_FACTORY = new DefaultFactory() {
+ public ELParser newParser() {
+ return new DefaultParser() {
+ protected Tokenizer createTokenizer() {
+ return TokenizerFactory.createJbossTokenizer();
+ }
+ public void dispose() {
+ super.dispose();
+ release(this);
+ }
+ };
+ }
+ };
+
public static ELParserFactory getJbossFactory() {
- return new ELParserFactory() {
- public ELParser createParser() {
- return new DefaultParser() {
- protected Tokenizer createTokenizer() {
- return TokenizerFactory.createJbossTokenizer();
- }
- };
+ return JBOSS_FACTORY;
+ }
+
+ private static abstract class DefaultFactory implements ELParserFactory {
+ protected Stack<ELParser> inUse = new Stack<ELParser>();
+ protected Stack<ELParser> free = new Stack<ELParser>();
+
+ public ELParser createParser() {
+ synchronized(this) {
+ if(!free.isEmpty()) {
+ //reuse
+ ELParser parser = free.pop();
+ inUse.push(parser);
+ return parser;
+ }
}
- };
+ ELParser parser = newParser();
+ synchronized(this) {
+ //new
+ inUse.push(parser);
+ }
+ return parser;
+ }
+
+ protected abstract ELParser newParser();
+
+ public void release(ELParser parser) {
+ synchronized(this) {
+ //release
+ boolean b = inUse.remove(parser);
+ if(!b) return;
+ free.push(parser);
+ }
+ }
}
private static abstract class DefaultParser implements ELParser {
ELParserImpl impl = new ELParserImpl();
List<SyntaxError> errors = null;
+ Tokenizer t = createTokenizer();
public ELModel parse(String source) {
return parse(source, 0, source.length());
}
public ELModel parse(String source, int start, int length) {
- Tokenizer t = createTokenizer();
- LexicalToken token = t.parse(source, start, length);
- errors = t.getErrors();
- ELModelImpl model = impl.parse(token);
- model.setSource(source);
- model.setErrors(errors);
- return model;
+ try {
+ LexicalToken token = t.parse(source, start, length);
+ errors = t.getErrors();
+ ELModelImpl model = impl.parse(token);
+ model.setSource(source);
+ model.setErrors(errors);
+ return model;
+ } finally {
+ t.dispose();
+ dispose();
+ }
}
- public List<SyntaxError> getSyntaxErrors() {
- return errors;
+ protected abstract Tokenizer createTokenizer();
+
+ public void dispose() {
+ errors = null;
}
- protected abstract Tokenizer createTokenizer();
}
}
Modified:
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/Tokenizer.java
===================================================================
---
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/Tokenizer.java 2008-10-29
12:54:37 UTC (rev 11282)
+++
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/Tokenizer.java 2008-10-29
12:57:57 UTC (rev 11283)
@@ -32,8 +32,8 @@
private String sourceString;
private int index = 0;
- private LexicalToken start = new LexicalToken(0, 0, "", -1000);
- private LexicalToken last = start;
+ private LexicalToken start;
+ private LexicalToken last;
private int state;
private Properties context = new Properties();
@@ -42,7 +42,21 @@
public Tokenizer() {}
+ /**
+ * Prepares this tokenizer to be reused with the same token descriptions and rules.
+ *
+ */
+ public void dispose() {
+ sourceString = null;
+ index = 0;
+ start = null;
+ last = null;
+ context.clear();
+ errors.clear();
+ }
+
public void setTokenDescriptions(ITokenDescription[] ds) {
+ tokenDescriptions.clear();
for (int i = 0; i < ds.length; i++) {
int type = ds[i].getType();
if(tokenDescriptions.containsKey(type)) {
@@ -57,6 +71,7 @@
}
public void setRules(IRule[] rules) {
+ this.rules.clear();
for (int i = 0; i < rules.length; i++) {
int[] ss = rules[i].getStartStates();
for (int j = 0; j < ss.length; j++) {
@@ -122,8 +137,17 @@
return result;
}
+ private static List<SyntaxError> EMPTY = new ArrayList<SyntaxError>();
+
+ /**
+ * Copies errors in order to reuse this object.
+ * @return
+ */
public List<SyntaxError> getErrors() {
- return errors;
+ if(errors.size() == 0) return EMPTY;
+ List<SyntaxError> copy = new ArrayList<SyntaxError>();
+ copy.addAll(errors);
+ return copy;
}
public void addToken(int type, int start, int end) {
@@ -195,4 +219,5 @@
public int getCurrentIndex() {
return index;
}
+
}
Modified:
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/TokenizerFactory.java
===================================================================
---
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/TokenizerFactory.java 2008-10-29
12:54:37 UTC (rev 11282)
+++
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/parser/TokenizerFactory.java 2008-10-29
12:57:57 UTC (rev 11283)
@@ -44,61 +44,69 @@
*/
public class TokenizerFactory {
+ private static ITokenDescription[] DEFAULT_DESCRIPTION_SET = new ITokenDescription[] {
+ ArgEndTokenDescription.INSTANCE,
+ ArgStartTokenDescription.INSTANCE,
+ DotTokenDescription.INSTANCE,
+ EndELTokenDescription.INSTANCE,
+ JavaNameTokenDescription.INSTANCE,
+ OperationTokenDescription.INSTANCE,
+ UnaryTokenDescription.INSTANCE,
+ PrimitiveValueTokenDescription.INSTANCE,
+ StartELTokenDescription.INSTANCE,
+ StringTokenDescription.INSTANCE,
+ WhiteSpaceTokenDescription.INSTANCE,
+ };
+
+ private static IRule[] DEFAULT_RULE_SET = new IRule[] {
+ ExpressionRule.INSTANCE,
+ CallRule.INSTANCE,
+ OperationRule.INSTANCE,
+ ErrorRecoveryRule.INSTANCE,
+ };
+
public static Tokenizer createDefaultTokenizer() {
Tokenizer t = new Tokenizer();
- t.setTokenDescriptions(new ITokenDescription[]{
- ArgEndTokenDescription.INSTANCE,
- ArgStartTokenDescription.INSTANCE,
- DotTokenDescription.INSTANCE,
- EndELTokenDescription.INSTANCE,
- JavaNameTokenDescription.INSTANCE,
- OperationTokenDescription.INSTANCE,
- UnaryTokenDescription.INSTANCE,
- PrimitiveValueTokenDescription.INSTANCE,
- StartELTokenDescription.INSTANCE,
- StringTokenDescription.INSTANCE,
- WhiteSpaceTokenDescription.INSTANCE,
- });
- t.setRules(new IRule[]{
- ExpressionRule.INSTANCE,
- CallRule.INSTANCE,
- OperationRule.INSTANCE,
- ErrorRecoveryRule.INSTANCE,
- });
+ t.setTokenDescriptions(DEFAULT_DESCRIPTION_SET);
+ t.setRules(DEFAULT_RULE_SET);
return t;
}
+ private static ITokenDescription[] JBOSS_DESCRIPTION_SET = new ITokenDescription[]{
+ ArgEndTokenDescription.INSTANCE,
+ ArgStartTokenDescription.INSTANCE,
+ CommaTokenDescription.INSTANCE,
+ DotTokenDescription.INSTANCE,
+ EndELTokenDescription.INSTANCE,
+ JavaNameTokenDescription.INSTANCE,
+ OperationTokenDescription.INSTANCE,
+ ParamEndTokenDescription.INSTANCE,
+ ParamStartTokenDescription.INSTANCE,
+ ExprStartTokenDescription.INSTANCE,
+ ExprEndTokenDescription.INSTANCE,
+ UnaryTokenDescription.INSTANCE,
+ PrimitiveValueTokenDescription.INSTANCE,
+ StartELTokenDescription.INSTANCE,
+ StringTokenDescription.INSTANCE,
+ WhiteSpaceTokenDescription.INSTANCE,
+ };
+
+ private static IRule[] JBOSS_RULE_SET = new IRule[] {
+ ExpressionRule.INSTANCE,
+ CallRule.INSTANCE,
+ OperationRule.INSTANCE,
+ ErrorRecoveryRule.INSTANCE,
+ };
+
public static Tokenizer createJbossTokenizer() {
Tokenizer t = new Tokenizer();
- t.setTokenDescriptions(new ITokenDescription[]{
- ArgEndTokenDescription.INSTANCE,
- ArgStartTokenDescription.INSTANCE,
- CommaTokenDescription.INSTANCE,
- DotTokenDescription.INSTANCE,
- EndELTokenDescription.INSTANCE,
- JavaNameTokenDescription.INSTANCE,
- OperationTokenDescription.INSTANCE,
- ParamEndTokenDescription.INSTANCE,
- ParamStartTokenDescription.INSTANCE,
- ExprStartTokenDescription.INSTANCE,
- ExprEndTokenDescription.INSTANCE,
- UnaryTokenDescription.INSTANCE,
- PrimitiveValueTokenDescription.INSTANCE,
- StartELTokenDescription.INSTANCE,
- StringTokenDescription.INSTANCE,
- WhiteSpaceTokenDescription.INSTANCE,
- });
- t.setRules(new IRule[]{
- ExpressionRule.INSTANCE,
- CallRule.INSTANCE,
- OperationRule.INSTANCE,
- ErrorRecoveryRule.INSTANCE,
- });
+ t.setTokenDescriptions(JBOSS_DESCRIPTION_SET);
+ t.setRules(JBOSS_RULE_SET);
return t;
}
public static void main(String[] args) {
- String text = "ioioio#{1.2e1}ioioio#{0}";
+ String text = "ioioio#{a(1.2e1i) + b c + d}ioioio#{0}";
//"#{a[b()['l'].j]}";
//"#{g11.g12.y13} #{#{ #{a14.b15(x.t.u(uu.ii[9], j)).b16(m17(v18(i19[2]).u20).)+
a21(c.).b.}";
//"#{not a.b(x,y) + s.h((6 != -8) & (7 + -iy88.g[9].h(7 div 8).i.j)+(8) ? 4 :
7,'p', a.b.c.d[null])}";
Modified:
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/resolver/Var.java
===================================================================
---
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/resolver/Var.java 2008-10-29
12:54:37 UTC (rev 11282)
+++
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/core/resolver/Var.java 2008-10-29
12:57:57 UTC (rev 11283)
@@ -51,7 +51,7 @@
if(el.length()>3 && el.startsWith("#{") &&
el.endsWith("}")) {
ELParser parser = factory.createParser();
ELModel model = parser.parse(el);
- if(model == null || parser.getSyntaxErrors().size() > 0) return null;
+ if(model == null || model.getSyntaxErrors().size() > 0) return null;
List<ELInstance> is = model.getInstances();
if(is.size() == 0) return null;
return is.get(0).getExpression();
Modified:
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/internal/core/model/ELModelImpl.java
===================================================================
---
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/internal/core/model/ELModelImpl.java 2008-10-29
12:54:37 UTC (rev 11282)
+++
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/internal/core/model/ELModelImpl.java 2008-10-29
12:57:57 UTC (rev 11283)
@@ -24,6 +24,7 @@
*
*/
public class ELModelImpl extends ELObjectImpl implements ELModel {
+ List<SyntaxError> errors = null;
String source;
List<ELInstance> instances = new ArrayList<ELInstance>();
int delta = 0;
@@ -72,6 +73,7 @@
}
public void setErrors(List<SyntaxError> errors) {
+ this.errors = errors;
for (SyntaxError e: errors) {
for (ELInstance i: instances) {
ELInstanceImpl im = (ELInstanceImpl)i;
@@ -84,10 +86,15 @@
}
+ public List<SyntaxError> getSyntaxErrors() {
+ return errors;
+ }
+
public void shift(int delta) {
this.delta = delta;
if(instances.size() > 0) {
instances.get(0).getFirstToken().shift(delta);
}
}
+
}
Modified:
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/internal/core/parser/ELParserImpl.java
===================================================================
---
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/internal/core/parser/ELParserImpl.java 2008-10-29
12:54:37 UTC (rev 11282)
+++
trunk/common/plugins/org.jboss.tools.common.el.core/src/org/jboss/tools/common/el/internal/core/parser/ELParserImpl.java 2008-10-29
12:57:57 UTC (rev 11283)
@@ -10,7 +10,6 @@
******************************************************************************/
package org.jboss.tools.common.el.internal.core.parser;
-import org.jboss.tools.common.el.core.model.ELObjectType;
import org.jboss.tools.common.el.core.parser.LexicalToken;
import org.jboss.tools.common.el.core.parser.Tokenizer;
import org.jboss.tools.common.el.internal.core.model.ELArgumentImpl;
@@ -49,30 +48,35 @@
*
*/
public class ELParserImpl {
- ELModelImpl model;
-
LexicalToken current;
public ELModelImpl parse(LexicalToken start) {
- model = new ELModelImpl();
- model.setFirstToken(start);
- current = start;
- while(current != null) {
- if(current.getType() == StartELTokenDescription.START_EL) {
- ELInstanceImpl instance = readELInstance();
- if(instance != null) {
- model.addInstance(instance);
- }
- } else if(!hasNextToken()) {
- break;
- } else {
- if(lookUpNextToken(current) == null) {
+ if(current != null) {
+ throw new RuntimeException("Cannot reuse parser while it is running.");
+ }
+ try {
+ ELModelImpl model = new ELModelImpl();
+ model.setFirstToken(start);
+ current = start;
+ while (current != null) {
+ if (current.getType() == StartELTokenDescription.START_EL) {
+ ELInstanceImpl instance = readELInstance();
+ if (instance != null) {
+ model.addInstance(instance);
+ }
+ } else if (!hasNextToken()) {
break;
+ } else {
+ if (lookUpNextToken(current) == null) {
+ break;
+ }
+ setNextToken();
}
- setNextToken();
}
+ return model;
+ } finally {
+ current = null;
}
- return model;
}
protected ELInstanceImpl readELInstance() {