/*******************************************************************************
* Copyright (c) 2007 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
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;
import org.jboss.tools.common.el.internal.core.parser.ELParserImpl;
/**
*
* @author V. Kabanovich
*
*/
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 DEFAULT_FACTORY;
}
private static ELParserFactory COLLECTION_FACTORY = new DefaultFactory() {
public ELParser newParser() {
return new DefaultParser() {
protected Tokenizer createTokenizer() {
return TokenizerFactory.createCollectionTokenizer();
}
public void dispose() {
super.dispose();
release(this);
}
};
}
};
/**
* Extends default factory by ability to parse method invocation without parameters
* to support access to collection and map elements by .iterator().next()
* @return
*/
public static ELParserFactory getCollectionFactory() {
return COLLECTION_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 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) {
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();
}
}
protected abstract Tokenizer createTokenizer();
public void dispose() {
errors = null;
}
}
}