EMMA Coverage Report (generated Tue Nov 24 15:49:41 EST 2009)
[all classes][atg.adapter.gsa]

COVERAGE SUMMARY FOR SOURCE FILE [SQLFileParser.java]

nameclass, %method, %block, %line, %
SQLFileParser.java0%   (0/1)0%   (0/19)0%   (0/665)0%   (0/145)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class SQLFileParser0%   (0/1)0%   (0/19)0%   (0/665)0%   (0/145)
<static initializer> 0%   (0/1)0%   (0/4)0%   (0/1)
RemoveWhiteSpaceFromString (String): String 0%   (0/1)0%   (0/7)0%   (0/2)
RemoveWhiteSpaceInFront (String): String 0%   (0/1)0%   (0/49)0%   (0/6)
SQLFileParser (): void 0%   (0/1)0%   (0/14)0%   (0/3)
checkForComments (String): String 0%   (0/1)0%   (0/43)0%   (0/7)
checkForEndLines (String): String 0%   (0/1)0%   (0/49)0%   (0/8)
checkForKeywords (String): boolean 0%   (0/1)0%   (0/110)0%   (0/13)
checkForSemiColons (String): String 0%   (0/1)0%   (0/14)0%   (0/3)
countFileArraySize (String []): int 0%   (0/1)0%   (0/6)0%   (0/2)
isStartOfIfExistsCommand (String): boolean 0%   (0/1)0%   (0/6)0%   (0/1)
isStartOfStoredProcedure (String): boolean 0%   (0/1)0%   (0/6)0%   (0/1)
main (String []): void 0%   (0/1)0%   (0/29)0%   (0/6)
parseIfExistsCommand (String, BufferedReader): String 0%   (0/1)0%   (0/37)0%   (0/7)
parseSQLFile (String): Collection 0%   (0/1)0%   (0/11)0%   (0/2)
parseSQLFiles (String []): Collection 0%   (0/1)0%   (0/35)0%   (0/9)
parseStoredProcedure (String, BufferedReader): String 0%   (0/1)0%   (0/36)0%   (0/7)
readFileAndLoadData (): List 0%   (0/1)0%   (0/198)0%   (0/63)
setFileNameArray (String []): void 0%   (0/1)0%   (0/4)0%   (0/2)
trimDebuggingCharacters (String): String 0%   (0/1)0%   (0/7)0%   (0/2)

1/**
2 * Copyright 2007 ATG DUST Project
3 * 
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * 
7 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8 * 
9 * Unless required by applicable law or agreed to in writing, software 
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and limitations under the License.
13 */
14 
15package atg.adapter.gsa;
16 
17import java.io.BufferedReader;
18import java.io.File;
19import java.io.FileInputStream;
20import java.io.InputStreamReader;
21import java.util.ArrayList;
22import java.util.Arrays;
23import java.util.Collection;
24import java.util.Iterator;
25import java.util.List;
26 
27import org.apache.log4j.Logger;
28 
29/**
30* THIS IS A REALLY SIMPLE APPLICATION THAT
31* TAKES A STRING ARRAY OF SQL FILES AND
32* RETURNS ALL OF THE SQL STATEMENTS THAT
33* MUST BE EXECUTED WITHIN THE FILES
34* DATE: MAY 23, 2000
35
36*
37* @author jb
38* 7/14/2002
39*/
40public class SQLFileParser
41{
42  
43  private static Logger log = Logger.getLogger(SQLFileParser.class);
44 
45// ****************************************
46// THERE IS ONLY ONE CLASS VARIABLE
47// FOR THIS CLASS.  THAT VARIABLE IS TO
48// STORE THE FILE NAMES.
49// ****************************************
50 
51    private String[] sFileNameArray = {""};
52    /** sets the names of files to be parsed */
53    private void setFileNameArray(String[] pFileNameArray)
54    {
55            sFileNameArray = pFileNameArray;
56    }
57    
58//    /** returns the names of files to be parsed */
59//    private String[] getFileNameArray()
60//    {
61//            return (sFileNameArray);
62//    }
63 
64// ============== CONSTRUCTORS =================
65      /**
66      * no arg constructor
67      */
68      public SQLFileParser() {}
69 
70// ================= PUBLIC METHODS =================
71 
72 
73        private String trimDebuggingCharacters(String sText)
74        {
75            if ( sText == null ) return sText;
76            return sText.trim();
77            /*
78                char[] ch = new char [sText.length()];
79                ch = sText.toCharArray();
80                String sTemp = "";
81                for (int i=0; i < sText.length(); i++)
82                {
83                        if ((ch[i] == '\n') || (ch[i] == '\r') || (ch[i] == '\t') || (ch[i] == '        '))
84                        {
85                                // Keep going
86                                sTemp = sTemp + " ";
87                        }
88                        else
89                        {
90                                sTemp = sTemp + ch[i];
91                        }
92                }
93                if (sTemp.length() > DEBUGGING_LENGTH)
94                {
95                        return (sTemp.substring(0,DEBUGGING_LENGTH));
96                }
97                else
98                {
99                        return (sTemp);
100                }
101              */
102        }
103 
104        private  String RemoveWhiteSpaceInFront (String sText)
105        {
106// **********************************************************************************
107//  THIS FUNCTION REMOVES WHITESPACE IN THE FRONT OF A STRING. FOR INSTANCE
108//  IF A STRING IS PASSED TO IT AS '   SPACE', THEN IT WILL RETURN 'SPACE.
109// **********************************************************************************
110                char[] ch = new char [sText.length()];
111                ch = sText.toCharArray();
112                //String sTemp;
113                for (int i=0; i < sText.length(); i++)
114                {
115                        if ((ch[i] == '\n') || (ch[i] == '\r') || (ch[i] == '\t')|| (ch[i] == ' ') || (ch[i] == '        '))
116                        {
117                                // Keep going
118                        }
119                        else
120                        {
121                                return (sText.substring (i, sText.length()));
122                        }
123                }
124                return (sText);
125        }
126 
127//        private  String RemoveWhiteSpaceInEnd (String sText)
128//        {
129//// **********************************************************************************
130////  THIS FUNCTION REMOVES WHITESPACE IN THE END OF A STRING. FOR INSTANCE
131////  IF A STRING IS PASSED TO IT AS 'SPACE   ', THEN IT WILL RETURN 'SPACE.
132//// **********************************************************************************
133//                char[] ch = new char [sText.length()];
134//                ch = sText.toCharArray();
135//                String sTemp;
136//                for (int i= sText.length() - 1; i > 0; i--)
137//                {
138//                        if ((ch[i] == '\n') || (ch[i] == '\r') || (ch[i] == '\t')|| (ch[i] == ' ') || (ch[i] == '        '))
139//                        {
140//                                // Keep going
141//                        }
142//                        else
143//                        {
144//                                return (sText.substring (0, i +1));
145//                        }
146//                }
147//                return (sText);
148//        }
149 
150        private  String RemoveWhiteSpaceFromString (String sText)
151        {
152            if ( sText == null ) return null;
153            return sText.trim();
154 
155// **********************************************************************************
156//  THIS FUNCTION REMOVES WHITESPACE IN THE FRONT AND END OF A STRING. FOR INSTANCE
157//  IF A STRING IS PASSED TO IT AS '   SPACE   ', THEN IT WILL RETURN 'SPACE.
158// **********************************************************************************
159/*
160                sText = RemoveWhiteSpaceInFront (sText);
161                sText = RemoveWhiteSpaceInEnd (sText);
162                return (sText);
163*/
164        }
165 
166 
167        private int countFileArraySize(String[] sArray)
168        {
169 
170// ****************************************
171// THIS IS A USEFUL FUNCTION TO
172// COUNT THE SIZE OF AN ARRAY. IT
173// TAKES AN ARRAY AS A PARAMETER
174// AND IT RETURNS AN INTEGER AS
175// THE COUNT.  IN THIS CASE WE
176// DO NOT NEED TO PASS THE ARRAY
177// SINCE IT IS A CLASS VARIABLE
178// ****************************************
179 
180                List<String> newList = Arrays.asList(sArray);
181                return (newList.size());
182        }
183 
184        private boolean checkForKeywords (String sLineRead)
185        {
186 
187// ****************************************
188// THIS IS ONE OF THE MOST CRITICAL
189// FUNCTIONS IN THIS PROGRAM.  IT
190// TAKES THE RESERVED WORDS FROM
191// SQL INSTALL SCRIPTS AND RESERVES
192// THEM WITHIN THIS APPLICATION.
193// EACH WORD LISTED BELOW STARTS
194// A SQL STATEMENT.
195// ****************************************
196 
197                String[] sKeywordList = {"BEGIN ", "CREATE ", "INSERT ", "UPDATE ", "DELETE ", "COMMIT ", "COMMIT", "ALTER ", "DROP ", "GRANT ", "GO", "IF OBJECT_ID"};
198                List<String> lList = Arrays.asList(sKeywordList);
199                int iArraySize = lList.size();
200 
201                sLineRead = RemoveWhiteSpaceInFront(sLineRead);
202                //sLineRead = sLineRead.trim();
203                // something about using trim() doesn't work with the overall logic of the program.
204 
205                for (int i=0; i< iArraySize; i++)
206                {
207                        if (sLineRead.toUpperCase().startsWith(sKeywordList[i].toUpperCase()) )
208                        {
209                            // we need to check more than just whether the line starts
210                            // with the keyword.  we also have to try to determine that
211                            // the keyword we found is actually NOT just the beginning of a
212                            // bigger word.  for example, GOogle.
213                            // so...
214                            if ( sLineRead.length() == sKeywordList[i].trim().length() ) {
215                                // if the whole line is just the keyword...
216                                return true;
217                            } else if ( sLineRead.charAt( sKeywordList[i].trim().length() ) == ' ' ) {
218                                // if the char after the word is a space
219                                return true;
220                            } else if ( sLineRead.charAt( sKeywordList[i].trim().length() ) == '(' ) {
221                                // if the char after the word is a right paren "("
222                                return true;
223                            }
224                        }
225                }
226                return (false);
227        }
228 
229        private String checkForComments(String sLineRead)
230        {
231 
232// ****************************************
233// THIS FUNCTION HAS ONE DUTY.  IT CHECKS
234// FOR LINES IN  SQL SCRIPT THAT HAVE
235// COMMENTS IN THEM.  IF IT FINDS A LINE
236// IN A SQL SCRIPT THAT WOULD BE RESERVED
237// FOR A COMMENT IT WILL SKIP THAT LINE.
238// ****************************************
239 
240                String[] sKeywordList = {"--", "//"};
241                List<String> lList = Arrays.asList(sKeywordList);
242                int iArraySize = lList.size();
243 
244                //sLineRead = sLineRead;
245                for (int i=0; i< iArraySize; i++)
246                {
247                        if (sLineRead.toUpperCase().indexOf(sKeywordList[i]) > -1)
248                        {
249                                return (sLineRead.substring(0,sLineRead.indexOf(sKeywordList[i])));
250                        }
251                }
252                return (sLineRead);
253        }
254 
255        private String checkForSemiColons(String sCurrentLine)
256        {
257 
258// ****************************************
259// THIS FUNCTION HAS ONE DUTY.  IT CHECKS
260// FOR SQL STATEMENTS THAT END IN THE
261// SEMICOLON PUNCTUATION AND REMOVES
262// THE SEMICOLON.
263// ****************************************
264 
265                if (sCurrentLine.indexOf(";") > -1)
266                {
267                        sCurrentLine = sCurrentLine.substring (0, sCurrentLine.indexOf(";"));
268                }
269                return (sCurrentLine);
270 
271        }
272 
273        private String checkForEndLines(String sCurrentLine)
274        {
275 
276// ****************************************
277// THIS FUNCTION HAS ONE DUTY.  IT CHECKS
278// FOR SQL STATEMENTS THAT END IN THE
279// SEMICOLON PUNCTUATION AND REMOVES
280// THE SEMICOLON.  Sometimes if there
281// is division in a view that is created
282// the end line will be used, and sometimes
283// it is used to execute a statement.
284// ****************************************
285                sCurrentLine = RemoveWhiteSpaceFromString(sCurrentLine);
286                int iLength = sCurrentLine.length() -2;
287                //int iIndex = sCurrentLine.indexOf("/");
288                if ((sCurrentLine.indexOf("/") > -1) && (sCurrentLine.indexOf("/") >= iLength))
289                {
290                        sCurrentLine = sCurrentLine.substring (0, sCurrentLine.indexOf("/"));
291                }
292                else if ((sCurrentLine.indexOf("/") > -1) && (sCurrentLine.indexOf("/") == 0))
293                {
294                        sCurrentLine = "";
295                }
296 
297                sCurrentLine = sCurrentLine + " ";
298                return (sCurrentLine);
299        }
300 
301 
302 
303        private List<String> readFileAndLoadData ()
304        {
305 
306// ****************************************
307// THIS FUNCTION IS THE ENGINE FOR THIS
308// APPLICATION. THIS FUNCTION OPENS
309// THE FIRST FILE FROM THE FILE ARRAY
310// LIST.  THEN IT READS THROUGH THE
311// FILE LINE BY LINE BUILDING A VECTOR
312// OF SQL SCRIPT COMMANDS.  WHEN IT IS
313// DONE PROCESSING IT PASSES A NEAT
314// VECTOR OF SQL COMMANDS TO THE
315// PROGRAM THAT CALLED THIS FUNCTION
316// ****************************************
317// THIS PARTICULAR METHOD IS LONG AND
318// TERRIBLE TO READ BECAUSE IT WAS WRITTEN
319// IN ONE SITTING. AND SINCE IT SEEMED
320// LIKE THE TYPE OF FUNCTION THAT LOOKS
321// SO BAD TO A CODE REVIEWER, BY LEAVING
322// IT IN THE CODE IT PROVIDES GOOD
323// HUMOR RELIEF FOR THE DEVELOPER GIVING
324// A CODE REVIEW TO THIS PROGRAM.
325// ****************************************
326 
327// ****************************************
328// VARIABLE DECLARATIONS
329                String sFileName = "";
330                String line = "";
331                String lineTemp = "";
332                String sSqlBuffer = "";
333                //String sFindSemiColon = "";
334 
335                boolean bKeywordAlreadyFound = false;
336                boolean bKeywordInString = false;
337 
338                List<String> vSql = new ArrayList<String>();
339 
340                BufferedReader in = null;
341 
342                File fFile = null;
343                FileInputStream fis = null;
344 
345                InputStreamReader Fin = null;
346 
347                //Object obj = null;
348 
349                int iSizeOfVector = countFileArraySize(sFileNameArray);
350// END VARIABLE DECLARATIONS
351// ****************************************
352 
353// ****************************************
354// LOOPING THROUGH THE VECTOR OF FILE NAMES
355                for (int iFile = 0; iFile < iSizeOfVector; iFile++)
356                {
357 
358                // GETTING THE FIRST FILE NAME FROM THE VECTOR
359                        sFileName = sFileNameArray[iFile];
360 
361                        try // Try to open the file
362                        {
363                                //File fFile = new File (sDirectory, sFilename);
364                                fFile = new File (sFileName);
365                                fis = new FileInputStream(fFile);
366                                Fin = new InputStreamReader(fis);
367                                in = new BufferedReader(Fin);
368 
369                                //if (isLoggingDebug()) logDebug ("Able to open file: " + sFileName);
370                        }
371                        catch (Exception e)
372                        {
373                        //        logError("* Error opening file :" + sFileName + ": *");
374                                return (vSql);
375                        } // Unable to open the file
376 
377 
378                        try // Try to read the file line by line
379                        {
380                                //String sSqlStatement = "";
381                                sSqlBuffer = "";
382                                // Open file and read first line
383                                line = in.readLine();
384 
385                                lineTemp = line;
386 
387                                while (line != null) // It is not the end of the file, LOOK FOR KEY WORDS
388                                {
389                                        //log.info ("DEBUG:" + line);
390 
391                                        lineTemp = line;
392                                        lineTemp = checkForComments(lineTemp);
393                                        bKeywordInString = checkForKeywords(lineTemp);
394 
395                                        // if this line is starting a stored procedure declaration, parse it
396                                        // specially. added this block to correctly parse stored procedures in oracle.
397                                        // marty - 7/11/2002
398                                        if ( bKeywordInString && isStartOfStoredProcedure( lineTemp ) ) {
399 
400                                                String command = parseStoredProcedure( lineTemp, in );
401                                                vSql.add( command );
402                                                line = in.readLine();
403                                                continue;
404                                        }
405 
406                                        // if this line is starting an 'if exists...' statement for MS SQL Server, parse
407                                        // if specially.  added to work around bug 64622
408                                        if ( bKeywordInString && isStartOfIfExistsCommand( lineTemp ) ) {
409                                                String command = parseIfExistsCommand( lineTemp, in );
410                                                vSql.add( command );
411                                                line = in.readLine();
412                                                continue;
413                                        }
414 
415                                        if (bKeywordAlreadyFound)
416                                        {
417                                                if (bKeywordInString)
418                                                {
419                                                        sSqlBuffer = checkForSemiColons(sSqlBuffer);
420                                                        sSqlBuffer = checkForEndLines(sSqlBuffer);
421                                                        vSql.add(sSqlBuffer);
422                                                        sSqlBuffer = lineTemp;
423                                                }
424                                                else // (!bKeywordInString}
425                                                {
426                                                        sSqlBuffer = sSqlBuffer + " " + lineTemp;
427                                                }
428                                        }
429                                        else
430                                        {
431                                                if (bKeywordInString)
432                                                {
433                                                        bKeywordAlreadyFound = bKeywordInString;
434                                                        sSqlBuffer = sSqlBuffer + lineTemp;
435                                                }
436                                        }
437 
438                                        //Get the next line
439                                        line = in.readLine();
440                                } // End while
441 
442                                try
443                                {
444                                        sSqlBuffer = checkForSemiColons(sSqlBuffer);
445                                        sSqlBuffer = checkForEndLines(sSqlBuffer);
446                                        vSql.add(sSqlBuffer);
447                                }
448                                catch (Exception ex)
449                                {
450                                        //logError ("No element to add" + ex);
451 
452                                }
453 
454                        }
455                        catch (Exception e)
456                        {
457                                //logError("Could not read one line in file: " + sFileName + "\n");
458                                return (vSql);
459                        } // Unable to read one of the lines in the file
460 
461                        try // To close the file streams
462                        {
463                                Fin.close();
464                                fis.close();
465                                //fFile.close();
466                        }
467                        catch (Exception ex)
468                        {
469                                //logError ("Unable to close files\n");
470                                return (vSql);
471                        } // If the files could not be closed
472                }
473                return (vSql);
474        }
475 
476        /** this method returns true if this line is the start of a check for whether an object exists
477         *  in MS SQL Server.  otherwise it returns false.
478         */
479        private boolean isStartOfIfExistsCommand( String pLine ) {
480            // i think this is only on MS SQL Server.  hard-coding the logic.
481            return pLine.trim().toUpperCase().startsWith("IF OBJECT_ID");
482        }
483 
484        /** used to parse an if-exists method.  the parsing logic is different than our usual behavior
485         *  so it has been special cased.
486         *  @return String the parsed SQL command
487         *  @exception Exception if an error occurs
488         */
489        private String parseIfExistsCommand( String pCommand, BufferedReader pIn )
490            throws Exception
491        {
492                // a pretty big hack, but just parse until we find the next "go"
493                String line = pIn.readLine();
494                if ( line != null ) line = line.trim();
495                 while ( line != null && (! line.toUpperCase().startsWith("GO")) )
496                 {
497                        pCommand = pCommand + " " + line;
498                        line = pIn.readLine();
499                        if ( line != null ) line = line.trim();
500                }
501 
502                return pCommand;
503        }
504 
505        /** this method returns true if this line is the start of a definition for a stored procedure.
506         *  otherwise, it returns false.
507         */
508         private boolean isStartOfStoredProcedure( String pLine ) {
509                 // i only know of this on oracle, so i'm temporarily coding it to work specifically
510                 // with oracle.
511                 return pLine.trim().toUpperCase().startsWith( "CREATE OR REPLACE PROCEDURE" );
512         }
513 
514        /** this method is used to parse a stored procedure.  since stored procedures may contain
515         *  sub-commands within them, we use a special process to parse them.
516         *
517         *  @return String the parsed SQL command
518         *  @exception Exception if an error occurs
519         */
520        private String parseStoredProcedure( String pCommand, BufferedReader pIn )
521                throws Exception
522        {
523                // this is pretty much a total hack, but i just want to get it working for now
524                // ASSUME we just parse until we find a line that starts with "/"
525                String line = pIn.readLine();
526                if ( line != null ) line = line.trim();
527                 while ( line != null && (! line.startsWith("/")) )
528                 {
529                        pCommand = pCommand + " " + line;
530                        line = pIn.readLine();
531                        if ( line != null ) line = line.trim();
532                }
533 
534                return pCommand;
535        }
536 
537 
538        public synchronized Collection<String> parseSQLFiles( String[] pFiles )
539        {
540                setFileNameArray( pFiles );
541// ****************************************
542// THIS FUNCTION CALLS THE FUNCTION THAT
543// READS THROUGH THE ARRAY OF FILES PASSED
544// TO IT AND IT RETURNS A VECTOR OF SQL
545// STATEMENTS.  MOST OF THESE WILL TEND
546// TO BE CREATE AND DROP STATEMENTS.
547// ****************************************
548                List<String> v = new ArrayList<String>();
549                v = readFileAndLoadData();
550                String s = "";
551                for (int i=0;i<v.size();i++)
552                {
553                        s = v.get(i).toString();
554                        s = trimDebuggingCharacters (s);
555 
556                        if ( logToSystemOut ) {
557                                //log.info("\n\n" + s );
558                        } else {
559                          //  if (isLoggingInfo ()) logInfo(s);
560                        }
561                }
562 
563                return v;
564        }
565 
566        public Collection<String> parseSQLFile( String pFile )
567        {
568            String[] files = { pFile };
569            return parseSQLFiles( files );
570        }
571 
572        // This is useful for debugging this application
573        public boolean logToSystemOut = false;
574        public static void main (String[] args)
575        {
576                SQLFileParser t = new SQLFileParser();
577                t.logToSystemOut = true;
578                Iterator<String> cmds = t.parseSQLFiles( args ).iterator();
579                  while ( cmds.hasNext() ) {
580                   log.info("\n\n" + cmds.next() );
581                  }
582        }
583 
584 
585 
586}
587 

[all classes][atg.adapter.gsa]
EMMA 2.0.5312 (C) Vladimir Roubtsov