001
002package gudusoft.gsqlparser.scriptWriter;
003
004import gudusoft.gsqlparser.EComparisonType;
005import gudusoft.gsqlparser.EExpressionType;
006import gudusoft.gsqlparser.ETokenType;
007import gudusoft.gsqlparser.TBaseType;
008import gudusoft.gsqlparser.TSourceToken;
009import gudusoft.gsqlparser.TSourceTokenList;
010import gudusoft.gsqlparser.nodes.TExpression;
011
012import java.io.IOException;
013import java.io.Writer;
014import java.util.ArrayList;
015import java.util.List;
016
017public class TScriptWriter
018{
019
020        public void TScriptWriter( )
021        {
022
023        }
024
025
026        public void addComparisonOperatorByTokens( ArrayList<TSourceToken> tokens ) {
027                addSpace( 1 );
028                for(int i = 0; i < tokens.size(); i++){
029                        TSourceToken st = tokens.get(i);
030                        if(st.toString().equals(".")){
031                                addSymbol(st.toString());
032                        }
033                        else {
034                                if(i < tokens.size()-1 && tokens.get(i+1).toString().equals(".")){
035                                        addSymbol(st.toString());
036                                }
037                                else {
038                                        addSymbol(st.toString());
039                                        addSpace(1);
040                                }
041                        }
042                }
043        }
044
045
046        public void addComparisonOperator( EComparisonType comparisonType ) {
047                addComparisonOperator(comparisonType, null);
048        }
049
050        public void addComparisonOperator( EComparisonType comparisonType, TSourceToken defaultSymbolToken )
051        {
052                addSpace( 1 );
053                switch ( comparisonType )
054                {
055                        case equals :
056                                addSymbol( "=" );
057                                break;
058                        case nullSafeEquals:
059                                addSymbol( "<=>" );
060                                break;
061                        case greaterThan :
062                                addSymbol( ">" );
063                                break;
064                        case lessThan :
065                                addSymbol( "<" );
066                                break;
067                        case notEqualToBrackets :
068                                addSymbol( "<>" );
069                                break;
070                        case notEqualToCaret :
071                                addSymbol( "^=" );
072                                break;
073                        case notEqualToExclamation :
074                                addSymbol( "!=" );
075                                break;
076                        case greaterThanOrEqualTo :
077                                addSymbol( ">=" );
078                                break;
079                        case lessThanOrEqualTo :
080                                addSymbol( "<=" );
081                                break;
082                        case notGreaterThan :
083                                addSymbol( "!>" );
084                                break;
085                        case notGreaterThanToCaret :
086                                addSymbol( "^>" );
087                                break;
088                        case notLessThan :
089                                addSymbol( "!<" );
090                                break;
091                        case notLessThanToCaret :
092                                addSymbol( "^<" );
093                                break;
094                        default :
095                                if (defaultSymbolToken != null) {
096                                        addSymbol(defaultSymbolToken.astext);
097                                }
098                                break;
099                }
100                addSpace( 1 );
101        }
102
103        public void addUnaryOperator( EExpressionType expressionType )
104        {
105                switch ( expressionType )
106                {
107                        case unary_plus_t :
108                                addSymbol( "+" );
109                                break;
110                        case unary_minus_t :
111                                addSymbol( "-" );
112                                break;
113                        case unary_bitwise_not_t :
114                                addSymbol( "~" );
115                                break;
116                        case unary_prior_t :
117                                addKeyword( "prior" );
118                                break;
119                        case unary_connect_by_root_t :
120                                addKeyword( "connect_by_root" );
121                                break;
122                        default :
123                                break;
124                }
125
126        }
127
128        public void addBinaryOperator(TExpression node)
129        {
130                EExpressionType expressionType = node.getExpressionType();
131
132                if(expressionType == EExpressionType.collate_t){
133                        addKeyword("COLLATE");
134                        return;
135                }
136                addSpace( 1 );
137                switch ( expressionType )
138                {
139                        case arithmetic_plus_t :
140                                addSymbol( "+" );
141                                break;
142                        case arithmetic_minus_t :
143                                addSymbol( "-" );
144                                break;
145                        case arithmetic_times_t :
146                                addSymbol( "*" );
147                                break;
148                        case arithmetic_divide_t :
149                                addSymbol( node.getOperatorToken().toString());
150                                break;
151                        case arithmetic_modulo_t :
152                                addSymbol( "%" );
153                                break;
154                        case bitwise_and_t :
155                                addSymbol( "&" );
156                                break;
157                        case bitwise_or_t :
158                                addSymbol( "|" );
159                                break;
160                        case bitwise_exclusive_or_t :
161                                addSymbol( "^" );
162                                break;
163                        case bitwise_xor_t :
164                                addSymbol( "#" );
165                                break;
166                        case logical_and_t :
167                                addKeyword( "and" );
168                                break;
169                        case logical_or_t :
170                                addKeyword( "or" );
171                                break;
172                        case concatenate_t :
173                                addSymbol( "||" );
174                                break;
175                        case sqlserver_proprietary_column_alias_t :
176                                addSymbol( "=" );
177                                break;
178                        case left_join_t :
179                                addSymbol( "*=" );
180                                break;
181                        case right_join_t :
182                                addSymbol( "=*" );
183                                break;
184                        //add by grq issue=I7E3TC
185                        case exponentiate_t:
186                                addSymbol( "^" );
187                                break;
188                        //end by grq
189                }
190                addSpace( 1 );
191
192        }
193
194        private List<TSourceToken> tokenList = new ArrayList<TSourceToken>( );
195
196        public void reset( )
197        {
198                tokenList.clear( );
199        }
200
201        public void writeTo( Writer writer )
202        {
203
204                for ( TSourceToken st : tokenList )
205                {
206                        try
207                        {
208                                writer.write( st.toString( ) );
209                        }
210                        catch ( IOException e )
211                        {
212                                e.printStackTrace( );
213                        }
214                }
215        }
216
217        public boolean verifyTokens( TSourceTokenList originalTokens,
218                        boolean partialChecking )
219        {
220                boolean result = true;
221                int old = 0;
222                boolean startParenthesis = false;
223                int nestedParenthesis = 0;
224
225                for ( int i = 0; i < tokenList.size( ); i++ )
226                {
227                        if ( tokenList.get( i ).tokentype == ETokenType.ttkeyword )
228                        {
229                                // must a space after keyword
230                                if ( i != tokenList.size( ) - 1 )
231                                {
232                                        if ( ( tokenList.get( i + 1 ).tokencode == TBaseType.lexnewline )
233                                                        || ( tokenList.get( i + 1 ).tokencode == TBaseType.lexspace )
234                                                        || ( tokenList.get( i + 1 ).tokencode == '(' )
235                                                        || ( tokenList.get( i + 1 ).tokencode == ')' ) )
236                                        {
237                                                continue;
238                                        }
239                                        else
240                                        {
241                                                System.out.print( "lack space after keyword:"
242                                                                + tokenList.get( i ).toString( ) );
243                                                result = false;
244                                                break;
245                                        }
246                                }
247                        }
248
249                        if ( tokenList.get( i ).tokentype == ETokenType.ttidentifier )
250                        {
251                                // must a space between identifier and keyword/identifier
252                                if ( i != 0 )
253                                {
254                                        if ( ( tokenList.get( i - 1 ).tokentype == ETokenType.ttkeyword )
255                                                        || ( tokenList.get( i - 1 ).tokentype == ETokenType.ttidentifier ) )
256                                        {
257                                                System.out.print( "lack space between identifier and keyword:"
258                                                                + tokenList.get( i ).toString( ) );
259                                                result = false;
260                                                break;
261                                        }
262                                        else
263                                        {
264                                                continue;
265                                        }
266                                }
267                        }
268
269                }
270
271                if ( !result )
272                        return result;
273
274                for ( int i = 0; i < originalTokens.size( ); i++ )
275                {
276                        if ( ( originalTokens.get( i ).tokencode == TBaseType.lexnewline )
277                                        || ( originalTokens.get( i ).tokencode == TBaseType.lexspace )
278                                        || ( originalTokens.get( i ).tokentype == ETokenType.ttsimplecomment )
279                                        || ( originalTokens.get( i ).tokentype == ETokenType.ttbracketedcomment )
280                                        || ( originalTokens.get( i ).tokentype == ETokenType.ttsemicolon ) )
281                        {
282                                continue;
283                        }
284
285                        if ( partialChecking )
286                        {
287                                if ( originalTokens.get( i ).tokencode == '(' )
288                                {
289                                        startParenthesis = true;
290                                        nestedParenthesis++;
291                                }
292                                else if ( originalTokens.get( i ).tokencode == ')' )
293                                {
294                                        if ( nestedParenthesis > 0 )
295                                                nestedParenthesis--;
296                                        if ( ( nestedParenthesis == 0 ) && startParenthesis )
297                                        {
298                                                result = true;
299                                                break;
300                                        }
301                                }
302                        }
303
304                        result = false;
305                        for ( int j = old; j < tokenList.size( ); j++ )
306                        {
307                                if ( ( tokenList.get( j ).tokencode == TBaseType.lexnewline )
308                                                || ( tokenList.get( j ).tokencode == TBaseType.lexspace )
309                                                || ( tokenList.get( j ).tokentype == ETokenType.ttsimplecomment )
310                                                || ( tokenList.get( j ).tokentype == ETokenType.ttbracketedcomment )
311                                                || ( tokenList.get( j ).tokentype == ETokenType.ttsemicolon ) )
312                                {
313                                        continue;
314                                }
315
316                                if ( ( originalTokens.get( i ).tokencode == TBaseType.outer_join )
317                                                && ( tokenList.get( j ).tokencode == TBaseType.outer_join ) )
318                                {
319                                        result = true;
320                                }
321                                else
322                                {
323                                        result = originalTokens.get( i )
324                                                        .toString( )
325                                                        .equalsIgnoreCase( tokenList.get( j ).toString( ) );
326                                }
327
328                                old = j + 1;
329                                break;
330                        }
331
332                        if ( !result )
333                        {
334                                System.out.print( "source token:"
335                                                + originalTokens.get( i ).toString( )
336                                                + "("
337                                                + originalTokens.get( i ).lineNo
338                                                + ","
339                                                + originalTokens.get( i ).columnNo
340                                                + ")" );
341                                System.out.print( ", target token:"
342                                                + tokenList.get( old - 1 ).toString( )
343                                                + "("
344                                                + tokenList.get( old - 1 ).lineNo
345                                                + ","
346                                                + tokenList.get( old - 1 ).columnNo
347                                                + ")" );
348                                break;
349                        }
350                        // if (! result) break;
351                }
352
353                return result;
354        }
355
356        public void addSymbol( String symbol )
357        {
358                TSourceToken st = new TSourceToken( symbol );
359                addToken( st );
360        }
361
362        public void addSymbol( String symbol, int tokenCode )
363        {
364                TSourceToken st = new TSourceToken( symbol );
365                st.tokencode = tokenCode;
366                addToken( st );
367        }
368
369        public void addToken( TSourceToken st )
370        {
371                if ( ( tokenList.size( ) == 0 )
372                                && ( ( st.tokencode == TBaseType.lexspace ) || ( st.tokencode == TBaseType.lexnewline ) ) )
373                {
374                        // don't add space at the beginning
375                }
376                else
377                        tokenList.add( st );
378        }
379
380        public void addSpace( int count )
381        {
382                TSourceToken st = new TSourceToken( String.format( "%" + count + "s",
383                                " " ) );
384                st.tokencode = TBaseType.lexspace;
385                addToken( st );
386        }
387
388        public void addNewline( )
389        {
390                TSourceToken st = new TSourceToken( TBaseType.linebreak );
391                st.tokencode = TBaseType.lexnewline;
392                addToken( st );
393        }
394
395        public void addSemicolon( )
396        {
397                TSourceToken st = new TSourceToken( ";" );
398                st.tokentype = ETokenType.ttsemicolon;
399                addToken( st );
400        }
401
402        public void addIdentifier( String text )
403        {
404                TSourceToken st = new TSourceToken( text );
405                st.tokencode = TBaseType.ident;
406                st.tokentype = ETokenType.ttidentifier;
407                addToken( st );
408        }
409
410        public void acceptOracleHint( String text )
411        {
412                TSourceToken st = new TSourceToken( text );
413                st.tokencode = TBaseType.cmtslashstar;
414                st.tokentype = ETokenType.ttbracketedcomment;
415                addToken( st );
416        }
417
418        public void addKeyword( String text )
419        {
420                addKeyword( text, true );
421        }
422
423        public void addKeyword( String text, boolean spaceAround )
424        {
425                TSourceToken st = new TSourceToken( text );
426                st.tokentype = ETokenType.ttkeyword;
427                if ( spaceAround )
428                        addSpace( 1 );
429                addToken( st );
430                if ( spaceAround )
431                        addSpace( 1 );
432        }
433
434        public void addOperator( String text, ETokenType tokenType )
435        {
436                TSourceToken st = new TSourceToken( text );
437                st.tokentype = tokenType;
438                addSpace( 1 );
439                addToken( st );
440                addSpace( 1 );
441        }
442
443        public void addLiteral( String text )
444        {
445                TSourceToken st = new TSourceToken( text );
446                addToken( st );
447        }
448
449        public long getTokenListSize() {
450                return tokenList.size();
451        }
452
453        public void resetToPosition(long position) {
454                if (tokenList.size() > position && position >= 0) {
455                        while (tokenList.size() > position) {
456                                tokenList.remove(tokenList.size() - 1);
457                        }
458                }
459        }
460
461}