FileDocCategorySizeDatePackage
JQLC.javaAPI DocGlassfish v2 API14399Fri May 04 22:35:06 BST 2007com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc

JQLC

public class JQLC extends Object
author
Michael Bouschen
version
0.1 Note: this class allows to override its fields even after all the processing is done via the corresponding setXXX methods. This is not expected behavior. A better solution would be to change all setters to be private and have use a constructor to populate all the values. The constructor will call private setters to process the arguments.

Fields Summary
protected com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.TypeTable
typetab
protected ErrorMsg
errorMsg
protected Class
candidateClass
protected JQLAST
filterAST
protected JQLAST
importsAST
protected JQLAST
varsAST
protected JQLAST
paramsAST
protected JQLAST
orderingAST
protected JQLAST
resultAST
protected JQLAST
queryAST
private boolean
prefetchEnabled
protected Map
retrieveDescCache
RD cache, key is a string build from actual param values (see ParameterTable.getKeyForRetrieveDescCache). It's ok to use WeakHashMap from java.util, because the key is a string which is not referenced by the RD.
protected static final ResourceBundle
messages
I18N support
private static com.sun.jdo.spi.persistence.utility.logging.Logger
logger
The logger
Constructors Summary
public JQLC()


         
     
    
        this.errorMsg = new ErrorMsg();
    
Methods Summary
public voidcheckCandidates(java.lang.Class candidateClass, java.util.Collection candidateCollection)

        if (candidateClass == null)
            throw new JDOQueryException(
                I18NHelper.getMessage(messages, "jqlc.jqlc.generic.nocandidateclass")); //NOI18N
        if (!(candidateCollection instanceof ExtentCollection))
            throw new JDOUnsupportedOptionException(
                I18NHelper.getMessage(messages, "jqlc.jqlc.checkcandidates.memorycollection")); //NOI18N
        
        Class candidatePCClass = ((ExtentCollection)candidateCollection).getPersistenceCapableClass();
        if (candidatePCClass == null)
            throw new JDOFatalInternalException(
                I18NHelper.getMessage(messages, "jqlc.jqlc.checkcandidates.nullpc")); //NOI18N
        
        if (!candidateClass.getName().equals(candidatePCClass.getName()))
            throw new JDOQueryException(
                I18NHelper.getMessage(messages, "jqlc.jqlc.checkcandidates.mismatch", candidateClass.getName())); //NOI18N
    
public com.sun.jdo.spi.persistence.support.sqlstore.RetrieveDesccodeGen(com.sun.jdo.spi.persistence.support.sqlstore.PersistenceManager pm, ParameterTable paramtab)

        boolean finer = logger.isLoggable(Logger.FINER);
        boolean finest = logger.isLoggable(Logger.FINEST);
        RetrieveDesc rd = null;
        
        // check if a RetrieveDescriptor for the actual parameter constellation
        // is already available in the cache
        String key = paramtab.getKeyForRetrieveDescCache();

        synchronized(retrieveDescCache)
        {
            if (key != null)
                rd = (RetrieveDesc)retrieveDescCache.get(key);
            
            if (rd == null) {
                Optimizer optimizer = new Optimizer();
                optimizer.init(typetab, paramtab, errorMsg);
                optimizer.setASTFactory(JQLAST.Factory.getInstance());
                
                CodeGeneration codeGen = new CodeGeneration();
                codeGen.init(pm, typetab, paramtab, errorMsg, prefetchEnabled);
                codeGen.setASTFactory(JQLAST.Factory.getInstance());
                
                try
                {
                    JQLAST ast = queryAST;
                    
                    // The optimizer should treat query parameters as constant values,
                    // so I cannot call the optimzer before the query parameter values 
                    // are known. That's why optimization is part of codeGen which is 
                    // called by Query.execute and not called by Query.compile.
                    if (finer) logger.finer("LOG_JQLCStartPass", "optimizer"); //NOI18N
                    optimizer.query(ast);
                    // Do not store the optimizer result in the instance variable queryAST, 
                    // it cannot be reused by the next execution of this query. The next execute 
                    // might have different query parameter values, so the optimized AST is different. 
                    ast = (JQLAST)optimizer.getAST();
                    if (finest) logger.finest("LOG_JQLCDumpTree", ast.getTreeRepr("(optimized AST)")); //NOI18N
                    
                    if (finer) logger.finer("LOG_JQLCStartPass", "code generation"); //NOI18N
                    codeGen.query(ast);
                    rd = codeGen.getRetrieveDesc();
                    // add the current RetrieveDescriptor to the cache, 
                    // if the key is not null
                    if (key != null)
                        retrieveDescCache.put(key, rd);
                }
                catch (ANTLRException ex)
                {
                    errorMsg.fatal("JQLC.codeGen unexpected exception", ex); //NOI18N
                }
            }
            else {
                if (finer) logger.finest("LOG_JQLCReuseRetrieveDesc"); //NOI18N
            }
        }
        
        return rd;
    
private JQLParsercreateStringParser(java.lang.String text)

        return createStringParser(text, errorMsg);
    
public static JQLParsercreateStringParser(java.lang.String text, ErrorMsg errorMsg)
Returns a JQLParser instance parsing the specified text.

        Reader in = new StringReader(text);
        JQLLexer lexer = new JQLLexer(in);
        lexer.init(errorMsg);
        TokenBuffer buffer = new TokenBuffer(lexer);
        JQLParser parser = new JQLParser(buffer);
        parser.init(errorMsg);
        parser.setASTFactory(JQLAST.Factory.getInstance());
        return parser;
    
public voiddeclareImports(java.lang.String imports)

        if (imports == null)
        {
            importsAST = null;
            return;
        }

        try
        {
            JQLParser parser = createStringParser(imports);
            parser.parseImports();
            importsAST = (JQLAST)parser.getAST();        
        }
        catch (ANTLRException ex)
        {
            JQLParser.handleANTLRException(ex, errorMsg);
        }
    
public voiddeclareParameters(java.lang.String parameters)

        if (parameters == null)
        { 
            paramsAST = null;
            return;
        }
        
        try
        {
            JQLParser parser = createStringParser(parameters);
            parser.parseParameters();
            paramsAST = (JQLAST)parser.getAST();        
        }
        catch (ANTLRException ex)
        {
            JQLParser.handleANTLRException(ex, errorMsg);
        }
    
public voiddeclareVariables(java.lang.String variables)

        if (variables == null)
        {
            varsAST = null;
            return;
        }
        
        try
        {
            JQLParser parser = createStringParser(variables);
            parser.parseVariables();
            varsAST = (JQLAST)parser.getAST();        
        }
        catch (ANTLRException ex)
        {
            JQLParser.handleANTLRException(ex, errorMsg);
        }
    
public voidsemanticCheck(ParameterTable paramtab)

        boolean finer = logger.isLoggable(Logger.FINER);
        boolean finest = logger.isLoggable(Logger.FINEST);
        this.typetab = TypeTable.getInstance(candidateClass.getClassLoader());
        paramtab.init();
        Semantic semantic = new Semantic();
        semantic.init(typetab, paramtab, errorMsg);
        semantic.setASTFactory(JQLAST.Factory.getInstance());
        
        // create complete tree representation
        JQLAST classAST = semantic.checkCandidateClass(candidateClass);
        queryAST = semantic.createQueryAST(classAST, importsAST, paramsAST, varsAST, 
                                           orderingAST, resultAST, filterAST);
        
        if (finest) logger.finest("LOG_JQLCDumpTree", queryAST.getTreeRepr("(AST)")); //NOI18N

        // start semantic check
        try
        {
            if (finer) logger.finer("LOG_JQLCStartPass", "semantic analysis"); //NOI18N
            semantic.query(queryAST);
            queryAST = (JQLAST)semantic.getAST();
            if (finest) logger.finest("LOG_JQLCDumpTree", queryAST.getTreeRepr("(typed AST)")); //NOI18N
        }
        catch (ANTLRException ex)
        {
            errorMsg.fatal("JQLC.semanticCheck unexpected exception", ex); //NOI18N
        }
    
public voidsetClass(java.lang.Class candidateClass)

        // check valid candidate class definition
        if (candidateClass == null)
        {
            JDOQueryException ex =  new JDOQueryException(I18NHelper.getMessage(
                messages, "jqlc.jqlc.generic.nocandidateclass")); //NOI18N
            logger.throwing("jqlc.JQLC", "setClass", ex); //NOI18N
            throw ex;
        }
        this.candidateClass = candidateClass;
    
public voidsetFilter(java.lang.String filter)

        if (StringHelper.isEmpty(filter))
        {
            // If there is no filter specified use "true" as filter.
            // This is the case if 
            // - setFilter is not called at all (filter == null)
            // - the filter is empty or contians whitespecace only.
            // Internally the filter has to be specified, 
            // otherwise semantic analysis has problems with empty AST.
            filter = "true"; //NOI18N
        }
        
        try
        {
            JQLParser parser = createStringParser(filter);
            parser.parseFilter();
            filterAST = (JQLAST)parser.getAST();        
        }
        catch (ANTLRException ex)
        {
            JQLParser.handleANTLRException(ex, errorMsg);
        }
     
public voidsetOrdering(java.lang.String ordering)

        if (ordering == null)
        {
            orderingAST = null;
            return;
        }
        
        try
        {
            JQLParser parser = createStringParser(ordering);
            parser.parseOrdering();
            orderingAST = (JQLAST)parser.getAST();        
        }
        catch (ANTLRException ex)
        {
            JQLParser.handleANTLRException(ex, errorMsg);
        }
    
public voidsetPrefetchEnabled(boolean prefetchEnabled)

        this.prefetchEnabled = prefetchEnabled;
    
public voidsetResult(java.lang.String result)

        if (result == null)
        {
            resultAST = null;
            return;
        }
        
        try
        {
            JQLParser parser = createStringParser(result);
            parser.parseResult();
            resultAST = (JQLAST)parser.getAST();        
        }
        catch (ANTLRException ex)
        {
            JQLParser.handleANTLRException(ex, errorMsg);
        }