Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Firebird Open Source J2ee connector - jdbc driver
   *
   * Distributable under LGPL license.
   * You may obtain a copy of the License at http://www.gnu.org/copyleft/lgpl.html
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * LGPL License for more details.
  *
  * This file was created by members of the firebird development team.
  * All individual contributions remain the Copyright (C) of those
  * individuals.  Contributors to this file are either listed here or
  * can be obtained from a CVS history command.
  *
  * All rights reserved.
  */
 
 package org.firebirdsql.jdbc;


Parser for escaped procedure call.
 
 public class FBEscapedCallParser {
     
     private static final int NORMAL_STATE = 1;
     private static final int LITERAL_STATE = 2;
     private static final int BRACE_STATE = 4;
     private static final int CURLY_BRACE_STATE = 8;
     private static final int SPACE_STATE = 16;
     private static final int COMMA_STATE = 32;
     
     
     private int state = ;
 
     private int paramPosition;
     private int paramCount;
     
     private boolean isFirstOutParam;
     private boolean isNameProcessed;
     private boolean isExecuteWordProcessed;
     private boolean isProcedureWordProcessed;
     private boolean isCallWordProcessed;
     
     private int openBraceCount;
 
     private FBProcedureCall procedureCall;
     private FBEscapedParser escapedParser;
     
     public FBEscapedCallParser(int mode) {
         this. = new FBEscapedParser(mode);
     }
    
    
Returns the current state.
 
     protected int getState() { return ; }

    
Sets the current state.

Parameters:
state to enter.
Throws:
java.lang.IllegalStateException if the system cannot enter the desired state.
 
     protected void setState(int state) {
         this. = state;
     }

    
Returns if the system is in state state.

Parameters:
state we're testing
Returns:
true if the system is in state state.
 
     protected boolean isInState(int state) { return this. == state; }
    
    
Test the character to be the state switching character and switches the state if necessary.

Parameters:
testChar character to test
 
     protected void switchState(char testCharthrows FBSQLParseException {
         
         switch (testChar) {
             case '\'' : 
                 if (isInState())
                     setState();
                 else
                 if (isInState())
                     setState();
 
                 break;
                 
             case ' ' :
             case '\t' :
             case '\r' :
             case '\n' :
             case '\f' :
                if (!isInState())
                    setState();
                break;
                
            case ',' : 
                if (!isInState() && !isInState())
                    setState();
                
                break;
                
            case '(' :
            case ')' :
                if (isInState())
                    break;
                
                setState();
                
                break;
                
            case '{' :
            case '}' :
                if (!isInState())
                    setState();
                
                break;
            default :
                if (!isInState() && !isInState())
                setState();
        }
    }
    
    
    
Clean the SQL statement. This method removes leading and trailing spaces and removes leading and trailing curly braces if any.

Parameters:
sql SQL statement to clean up.
Returns:
cleaned up statement.
Throws:
FBSQLParseException if cleanup resulted in empty statement.
    private String cleanUpCall(String sqlthrows FBSQLParseException {
        StringBuffer cleanupBuffer = new StringBuffer(sql);
        
        // remove spaces at the beginning
        while(cleanupBuffer.length() > 0 && 
                Character.isSpaceChar(cleanupBuffer.charAt(0)))
            cleanupBuffer.deleteCharAt(0);
        
        // remove spaces at the end
        while(cleanupBuffer.length() > 0 && 
                Character.isSpaceChar(cleanupBuffer.charAt(cleanupBuffer.length() - 1)))
            cleanupBuffer.deleteCharAt(cleanupBuffer.length() - 1);
        
        if (cleanupBuffer.length() == 0)
            throw new FBSQLParseException(
                    "Escaped call statement was empty.");
        
        if (cleanupBuffer.charAt(0) == '{')
        	cleanupBuffer.deleteCharAt(0);
        
        if (cleanupBuffer.charAt(cleanupBuffer.length() - 1) == '}')
            cleanupBuffer.deleteCharAt(cleanupBuffer.length() - 1);
        
        return cleanupBuffer.toString();
    }
    
    
Check if either "call" keyword or "EXECUTE PROCEDURE" keyword processed.

Returns:
true if either one or another keyword were processed.
    private boolean isCallKeywordProcessed() {
    	return  || 
            ( && );
    }
    
    
Converts escaped parts in the passed SQL to native representation.

Parameters:
sql to parse
Returns:
native form of the sql.
    public FBProcedureCall parseCall(String sqlthrows FBSQLException {
        
    	sql = cleanUpCall(sql);
        
         = new FBProcedureCall();
        
         = false;
         = false;
         = false;
         = false;
        
         = false;
        
         = 0;
         = 0;
        
        setState();
        
        char[] sqlbuff = sql.toCharArray();
        StringBuffer buffer = new StringBuffer();
        
         for(int i = 0; i < sqlbuff.lengthi++) {
             switchState(sqlbuff[i]);
             if (isInState()) {
                 
                 // if we have an equal sign, most likely {? = call ...}
                 // syntax is used (there's hardly any place for this sign
                 // in procedure parameters). but to be sure, we check if 
                 // no brace is open and if buffer contains only '?'
                 if (sqlbuff[i] == '=') {
                     
                     if ( <= 0) {
                     
                         String token = buffer.toString().trim();
    
                         if ("?".equals(token) && ! && !) {
                             
                             FBProcedureParam param = 
                                 .addParam(token);
                             
                             ++;
                             param.setIndex();
                             
                              = true;
                             ++;
                             
                             buffer = new StringBuffer();
                             continue;
                         }
                     }
                 }
                     
                 buffer.append(sqlbuff[i]);
                 
             } else
             if (isInState()) {
                 
                 if (buffer.length() == 0) {
                     setState();
                     continue;
                 }
                 
                 if ( > 0) {
                     buffer.append(sqlbuff[i]);
                     setState();
                     continue;
                 }
                 
                 String token = buffer.toString().trim();
                 // if procedure name was not yet processed, process
                 // the token; we look for the sequence EXECUTE PROCEDURE <name>
                 // otherwise go into normal state to enable next transitions.
                 if (!) {
                     boolean tokenProcessed = processToken(token);
                     if (tokenProcessed) {
                     	buffer = new StringBuffer();
                        setState();
                        if (){
                            // If we just found a name, fast-forward to the 
                            // opening parenthesis, if there is one
                            int j = i;
                            while (j < sqlbuff.length - 1 
                                && Character.isWhitespace(sqlbuff[j])) j++;
                            if (sqlbuff[j] == '('
                                i = j;
                        }
                     }
                 } else {
                     buffer.append(sqlbuff[i]);
                     setState();
                 }
                 
             } else
             if (isInState()) {
                 
                 // if we have an opening brace and we already processed
                 // EXECUTE PROCEDURE words, but still do not have procedure
                 // name set, we can be sure that buffer contains procedure 
                 // name.
                 boolean isProcedureName = 
                     sqlbuff[i] == '(' &&
                     isCallKeywordProcessed() &&
                     !;
                 
                 if (isProcedureName) {
                     String token = buffer.toString().trim();
                     
                     if ("".equals(token))
                         throw new FBSQLParseException(
                             "Procedure name is empty.");
                     
                     .setName(token);
                      = true;
                     
                     buffer = new StringBuffer();
                     
                 } else {
                     buffer.append(sqlbuff[i]);
                 
                     if (sqlbuff[i] == '(')
                         ++;
                     else
                         --;
                 }
                 
                 setState();
                 
             } else
             if (isInState()) {
                
                buffer.append(sqlbuff[i]);
                setState();
                
             } else
             if (isInState()) {
                 
                 if ( > 0) {
                     buffer.append(sqlbuff[i]);
                     continue;
                 }
                 
                 String param = processParam(buffer.toString());
                 buffer = new StringBuffer();
                 
                 FBProcedureParam callParam = 
                     .addParam(param);
                 
                 if (callParam.isParam()) {
                     ++;
                     callParam.setIndex();
                 }
                 
                 ++;
                 
                 setState();
                 
             } else
             if (isInState()) 
                 buffer.append(sqlbuff[i]);
         }
         if (buffer.length() == 0) 
             return ;
         
         // remove spaces at the beginning and the end
         while(Character.isSpaceChar(buffer.charAt(0)))
             buffer.deleteCharAt(0);
         
         while(Character.isSpaceChar(buffer.charAt(buffer.length() - 1)))
             buffer.deleteCharAt(buffer.length() - 1);
         // if buffer starts with '(', remove it, 
         // we do not want this thing to bother us
         if (buffer.charAt(0) == '(')
             buffer.deleteCharAt(0);
         
         // if buffer ends with ')', remove it
         // it should match an opening brace right after the procedure
         // name, and we assume that all syntax check was already done.
         if (buffer.charAt(buffer.length() - 1) == ')')
             buffer.deleteCharAt(buffer.length() - 1);
         
         // if there's something in the buffer, treat it as last param
         if(null == .getName() && !) {
             .setName(buffer.toString());
         } else {
             FBProcedureParam callParam = 
                 .addParam(buffer.toString());
             
             if (callParam.isParam()) {
                 ++;
                 callParam.setIndex();
             }
         }
         
        return ;
    }
    
    
Process token. This method detects procedure call keywords and sets appropriate flags. Also it detects procedure name and sets appropriate filed in the procedure call object.

Parameters:
token token to process.
Returns:
true if token was understood and processed.
    protected boolean processToken(String token) {
        if ("EXECUTE".equalsIgnoreCase(token) && 
                ! && ! && !) {
             = true;
            return true;
        }
        
        if ("PROCEDURE".equalsIgnoreCase(token) &&
                 && ! && !) {
             = true;
            return true;
        }
        
        if ("call".equalsIgnoreCase(token) && ! && !) {
        	 = true;
            return true;
        }
        
            .setName(token);
             = true;
            return true;
        }
        
        return false;
    }
    
    
Pre-process parameter. This method checks if there is escaped call inside and converts it to the native one.

Parameters:
param parameter to process.
Returns:
processed parameter.
Throws:
FBSQLParseException if parameter cannot be correctly parsed.
    protected String processParam(String paramthrows FBSQLException {
        return .parse(param);
    }
New to GrepCode? Check out our FAQ X