package net.atos.optimus.common.tools.jdt;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import net.atos.optimus.common.tools.logging.OptimusLogger;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
/**
* Singleton that wraps the AST.JLS & Java versions mapping. The aim here is to
* be able to retrieve the JLS value according to the corresponding project or
* to get the highest possible !
*
* @author mvanbesien (mvaawl@gmail.com)
* @since 1.1
*
*/
public enum ASTParserFactory {
/**
* Singleton instance
*/
INSTANCE;
private static final String RETURNED_AST_WITH_DEFAULT_JLS = "[ASTParserFactory] Request for parser with default Level requested. Level is [%s].";
private static final String RETURNED_AST_WITH_JLS = "[ASTParserFactory] Compliance for project [%s] is [%s]. Ast Level returned is [%s].";
private static final String DEFAULT_JLS_MESSAGE = "[ASTParserFactory] JLS value used as default is [%s].";
/**
* @see JavaCore.VERSION_1_8
*/
private static final String JAVA8 = "1.8";
/**
* @see JavaCore.VERSION_1_7
*/
private static final String JAVA7 = "1.7";
/**
* @see JavaCore.VERSION_1_6
*/
private static final String JAVA6 = "1.6";
/**
* @see JavaCore.VERSION_1_5
*/
private static final String JAVA5 = "1.5";
/**
* @see JavaCore.VERSION_1_4
*/
private static final String JAVA4 = "1.4";
/**
* @see JavaCore.VERSION_1_3
*/
private static final String JAVA3 = "1.3";
/**
* @see AST.JLS2
*/
private static final int ASTJLS2 = 2;
/**
* @see AST.JLS3
*/
private static final int ASTJLS3 = 3;
/**
* @see AST.JLS4
*/
private static final int ASTJLS4 = 4;
/**
* @see AST.JLS8
*/
private static final int ASTJLS8 = 8;
/**
* Mapping between the java version and the AST level
*/
private Map<String, Integer> jlsMapping;
/**
* Default ast level to use, if mapping is not resolveable or if no
* project/compilation is found
*/
private Integer jlsDefaultLevel;
/*
*
*/
private ASTParserFactory() {
jlsMapping = new LinkedHashMap<String, Integer>();
jlsMapping.put(ASTParserFactory.JAVA3, ASTParserFactory.ASTJLS2);
jlsMapping.put(ASTParserFactory.JAVA4, ASTParserFactory.ASTJLS2);
jlsMapping.put(ASTParserFactory.JAVA5, ASTParserFactory.ASTJLS3);
jlsMapping.put(ASTParserFactory.JAVA6, ASTParserFactory.ASTJLS3);
jlsMapping.put(ASTParserFactory.JAVA7, ASTParserFactory.ASTJLS4);
jlsMapping.put(ASTParserFactory.JAVA8, ASTParserFactory.ASTJLS8);
// Defines the default value of AST from taking all the values, in
// decreasing order, and try to instanciate them as soon as one is
// created
int[] jlsLevelsDesc = new int[] { /* ASTParserFactory.ASTJLS8, */ASTParserFactory.ASTJLS4,
ASTParserFactory.ASTJLS3, ASTParserFactory.ASTJLS2 };
for (int i = 0; i < jlsLevelsDesc.length && jlsDefaultLevel == null; i++) {
int astLevel = jlsLevelsDesc[i];
try {
ASTParser parser = ASTParser.newParser(astLevel);
if (parser != null) {
jlsDefaultLevel = astLevel;
if (OptimusLogger.logger.isLoggable(Level.INFO)) {
OptimusLogger.logger.info(String.format(DEFAULT_JLS_MESSAGE, jlsDefaultLevel));
}
}
} catch (IllegalArgumentException iae) {
// Swallow it.
}
}
}
/**
* Creates a new ASTParser, with AST level corresponding as the compliance
* level specified in the project it is contained by.
*
* @param compilationUnit
* @return
*/
public ASTParser newParserFor(ICompilationUnit compilationUnit) {
return this.newParserFor(compilationUnit != null ? compilationUnit.getJavaProject() : null);
}
/**
* Creates a new ASTParser, with AST level corresponding as the compliance
* level specified in the project
*
* @param javaProject
* @return
*/
public ASTParser newParserFor(IJavaProject javaProject) {
if (javaProject != null && javaProject.exists()) {
Map<?, ?> options = javaProject.getOptions(true);
Object object = options.get(JavaCore.COMPILER_COMPLIANCE);
if (object != null) {
Integer astLevel = jlsMapping.get(object);
if (astLevel != null) {
try {
if (OptimusLogger.logger.isLoggable(Level.INFO)) {
OptimusLogger.logger.info(String.format(RETURNED_AST_WITH_JLS,
javaProject.getElementName(), object, astLevel));
}
return ASTParser.newParser(astLevel);
} catch (IllegalArgumentException iae) {
// Swallow it.
}
}
}
}
return newParser();
}
/**
* Creates new ASTParser with highest possible JLS level.
*
* @return
*/
public ASTParser newParser() {
if (OptimusLogger.logger.isLoggable(Level.INFO)) {
OptimusLogger.logger.info(String.format(RETURNED_AST_WITH_DEFAULT_JLS, this.jlsDefaultLevel));
}
return ASTParser.newParser(this.jlsDefaultLevel);
}
}