001
002package gudusoft.gsqlparser.pp.processor;
003
004import gudusoft.gsqlparser.TStatementList;
005import gudusoft.gsqlparser.pp.logger.PPLogger;
006import gudusoft.gsqlparser.pp.para.GFmtOpt;
007import gudusoft.gsqlparser.pp.para.styleenums.TAlignOption;
008import gudusoft.gsqlparser.pp.para.styleenums.TAlignStyle;
009import gudusoft.gsqlparser.pp.para.styleenums.TLinefeedsCommaOption;
010import gudusoft.gsqlparser.pp.processor.type.alter.AlterTableOptionItemAlignProcessor;
011import gudusoft.gsqlparser.pp.processor.type.comm.AbstractProcessor;
012import gudusoft.gsqlparser.pp.processor.type.comm.AlignAliasProcessor;
013import gudusoft.gsqlparser.pp.processor.type.comm.AppendNewLineAfterAndBeforeReverseKeyWordProcessor;
014import gudusoft.gsqlparser.pp.processor.type.comm.AppendNewLineAfterReverseKeyWordProcessor;
015import gudusoft.gsqlparser.pp.processor.type.comm.AppendNewLineBeforeKeyWordProcessor;
016import gudusoft.gsqlparser.pp.processor.type.comm.AppendNewLineBeforeReverseKeyWordProcessor;
017import gudusoft.gsqlparser.pp.processor.type.comm.CapitalisationProcessor;
018import gudusoft.gsqlparser.pp.processor.type.comm.CaseWhenProcessor;
019import gudusoft.gsqlparser.pp.processor.type.comm.ColumnlistCommaProcessor;
020import gudusoft.gsqlparser.pp.processor.type.comm.CombineWhitespaceAndClearReturnProcessor;
021import gudusoft.gsqlparser.pp.processor.type.comm.DistinctKeyWordProcessor;
022import gudusoft.gsqlparser.pp.processor.type.comm.ExpressionProcessor;
023import gudusoft.gsqlparser.pp.processor.type.comm.StmtListProcessor;
024import gudusoft.gsqlparser.pp.processor.type.createtable.CreateTableBEInNewLineProcessor;
025import gudusoft.gsqlparser.pp.processor.type.createtable.CreateTableConstraintAlignProcessor;
026import gudusoft.gsqlparser.pp.processor.type.createtable.CreateTableItemAlignProcessor;
027import gudusoft.gsqlparser.pp.processor.type.createview.CreateViewReturnProcessor;
028import gudusoft.gsqlparser.pp.processor.type.declare.DeclareVarItemAlignProcessor;
029import gudusoft.gsqlparser.pp.processor.type.delete.DeleteKeyWordAlignProcessor;
030import gudusoft.gsqlparser.pp.processor.type.execute.ExecParaNewLineProcessor;
031import gudusoft.gsqlparser.pp.processor.type.ifstmt.IfStmtBEProcessor;
032import gudusoft.gsqlparser.pp.processor.type.insert.AppendLineAfterInsertTableNameProcessor;
033import gudusoft.gsqlparser.pp.processor.type.insert.InsertKeyWordAlignProcessor;
034import gudusoft.gsqlparser.pp.processor.type.insert.InsertOutputClauseProcessor;
035import gudusoft.gsqlparser.pp.processor.type.insert.InsertValuesParenthsesAdjustProcessor;
036import gudusoft.gsqlparser.pp.processor.type.merge.AppendLineAfterMergeTableNameProcessor;
037import gudusoft.gsqlparser.pp.processor.type.merge.MergeKeyWordAlignProcessor;
038import gudusoft.gsqlparser.pp.processor.type.merge.MergeWhenClauseProcessor;
039import gudusoft.gsqlparser.pp.processor.type.plsql.BeginAndEndProcessor;
040import gudusoft.gsqlparser.pp.processor.type.plsql.CreateFuncFirstParamInNewlineProcessor;
041import gudusoft.gsqlparser.pp.processor.type.plsql.CreateFuncLeftBEProcessor;
042import gudusoft.gsqlparser.pp.processor.type.plsql.CreateFuncReturnsTableProcessor;
043import gudusoft.gsqlparser.pp.processor.type.plsql.CreateFuncRightBEProcessor;
044import gudusoft.gsqlparser.pp.processor.type.plsql.CreateFuncWSPaddingParenthesesProcessor;
045import gudusoft.gsqlparser.pp.processor.type.plsql.PlsqlIfStmtBEProcessor;
046import gudusoft.gsqlparser.pp.processor.type.rtn.ReturnStmtProcessor;
047import gudusoft.gsqlparser.pp.processor.type.select.CTEProcessor;
048import gudusoft.gsqlparser.pp.processor.type.select.JoinOnProcessor;
049import gudusoft.gsqlparser.pp.processor.type.select.SelectKeyWordAlignProcessor;
050import gudusoft.gsqlparser.pp.processor.type.select.UnionProcessor;
051import gudusoft.gsqlparser.pp.processor.type.update.UpdateKeyWordAlignProcessor;
052import gudusoft.gsqlparser.stmt.TBlockSqlStatement;
053import gudusoft.gsqlparser.stmt.TIfStmt;
054
055import java.util.ArrayList;
056import java.util.List;
057import java.util.Map;
058import java.util.concurrent.ConcurrentHashMap;
059
060/**
061 * a formattor para processor factory used for create the processor instance
062 * 
063 * @author zhoujun
064 * 
065 */
066public class ProcessorFactory
067{
068
069        /**
070         * the processor container
071         */
072        private volatile static Map<String, AbstractProcessor> processors = new ConcurrentHashMap<String, AbstractProcessor>( );
073
074        private static Object object = new Object( );
075
076        /**
077         * create the comma processor
078         * 
079         * @param option
080         * @return instance
081         */
082        public static ColumnlistCommaProcessor createColumnlistCommaProcessor(
083                        GFmtOpt option, TLinefeedsCommaOption commaOption,
084                        TAlignStyle option2 )
085        {
086                return (ColumnlistCommaProcessor) create( ColumnlistCommaProcessor.class,
087                                option,
088                                commaOption,
089                                option2 );
090        }
091
092        /**
093         * create the alias processor
094         * 
095         * @param option
096         * @return instance
097         */
098        public static AlignAliasProcessor createAlignAliasProcessor(
099                        GFmtOpt option, boolean option2, TAlignStyle style )
100        {
101                return (AlignAliasProcessor) create( AlignAliasProcessor.class,
102                                option,
103                                option2,
104                                style );
105        }
106
107        /**
108         * create the new line processor for item list
109         * 
110         * @param option
111         * @return
112         */
113        public static AppendNewLineAfterReverseKeyWordProcessor appendNewLineAfterReverseKeyWordProcessor(
114                        GFmtOpt option, boolean isItemInNewLine, String keyword )
115        {
116                return (AppendNewLineAfterReverseKeyWordProcessor) create( AppendNewLineAfterReverseKeyWordProcessor.class,
117                                option,
118                                isItemInNewLine,
119                                keyword );
120        }
121
122        /**
123         * create the distinct keyword processor
124         * 
125         * @param isTreatDistinctAsVirtualColumn
126         * @return
127         */
128        public static DistinctKeyWordProcessor createDistinctKeyWordProcessor(
129                        GFmtOpt option, boolean isTreatDistinctAsVirtualColumn )
130        {
131                return (DistinctKeyWordProcessor) create( DistinctKeyWordProcessor.class,
132                                option,
133                                isTreatDistinctAsVirtualColumn );
134        }
135
136        /**
137         * create the keyword in new line processor
138         * 
139         * @param inNewLine
140         * @return
141         */
142        public static AppendNewLineAfterAndBeforeReverseKeyWordProcessor appendNewLineAfterAndBeforeReverseKeyWordProcessor(
143                        GFmtOpt option, boolean inNewLine, String startKeyword,
144                        String endKeyword )
145        {
146                return (AppendNewLineAfterAndBeforeReverseKeyWordProcessor) create( AppendNewLineAfterAndBeforeReverseKeyWordProcessor.class,
147                                option,
148                                inNewLine,
149                                startKeyword,
150                                endKeyword );
151        }
152
153        /**
154         * create the join on processor for the select statement
155         * 
156         * @param selectFromclauseJoinOnInNewline
157         * @return
158         */
159        public static JoinOnProcessor createJoinOnProcessor( GFmtOpt option,
160                        boolean selectFromclauseJoinOnInNewline,
161                        boolean alignJoinWithFromKeyword )
162        {
163                return (JoinOnProcessor) create( JoinOnProcessor.class,
164                                option,
165                                selectFromclauseJoinOnInNewline,
166                                alignJoinWithFromKeyword );
167        }
168
169        /**
170         * create the union processor for the select statement
171         * 
172         * @param option
173         * @return
174         */
175        public static UnionProcessor createUnionProcessor( GFmtOpt option )
176        {
177                return (UnionProcessor) create( UnionProcessor.class, option );
178        }
179
180        /**
181         * create the expression processor for all statements
182         * 
183         * @param option
184         * @return
185         */
186        public static ExpressionProcessor createExpressionProcessor( GFmtOpt option )
187        {
188                return (ExpressionProcessor) createExpressionProcessor( option, false );
189        }
190
191        public static ExpressionProcessor createExpressionProcessor(
192                        GFmtOpt option, Boolean isAndUnderWhere )
193        {
194                return (ExpressionProcessor) create( ExpressionProcessor.class,
195                                option,
196                                isAndUnderWhere );
197        }
198
199        /**
200         * create the processor used to process the 'case when' paramters
201         * 
202         * @param option
203         * @param caseWhenThenInSameLine
204         * @param indentCaseFromSwitch
205         * @return
206         */
207        public static CaseWhenProcessor createCaseWhenProcessor( GFmtOpt option,
208                        Boolean caseWhenThenInSameLine, Integer indentCaseFromSwitch )
209        {
210                return (CaseWhenProcessor) create( CaseWhenProcessor.class,
211                                option,
212                                caseWhenThenInSameLine,
213                                indentCaseFromSwitch );
214        }
215
216        /**
217         * create the processor used to align the keywords in select statement
218         * 
219         * @param option
220         * @return
221         */
222        public static SelectKeyWordAlignProcessor createSelectKeyWordAlignProcessor(
223                        GFmtOpt option )
224        {
225                return (SelectKeyWordAlignProcessor) create( SelectKeyWordAlignProcessor.class,
226                                option );
227        }
228
229        public static MergeKeyWordAlignProcessor createMergeKeyWordAlignProcessor(
230                        GFmtOpt option )
231        {
232                return (MergeKeyWordAlignProcessor) create( MergeKeyWordAlignProcessor.class,
233                                option );
234        }
235
236        /**
237         * create the processor used to align the keywords in insert statement
238         * 
239         * @param option
240         * @return
241         */
242        public static InsertKeyWordAlignProcessor createInsertKeyWordAlignProcessor(
243                        GFmtOpt option )
244        {
245                return (InsertKeyWordAlignProcessor) create( InsertKeyWordAlignProcessor.class,
246                                option );
247        }
248
249        /**
250         * create the processor used to append an new line after the table name
251         * 
252         * @param option
253         * @return
254         */
255        public static AppendLineAfterInsertTableNameProcessor createAppendLineAfterInsertTableNameProcessor(
256                        GFmtOpt option )
257        {
258                return (AppendLineAfterInsertTableNameProcessor) create( AppendLineAfterInsertTableNameProcessor.class,
259                                option );
260        }
261
262        public static AppendLineAfterMergeTableNameProcessor createAppendLineAfterMergeTableNameProcessor(
263                        GFmtOpt option )
264        {
265                return (AppendLineAfterMergeTableNameProcessor) create( AppendLineAfterMergeTableNameProcessor.class,
266                                option );
267        }
268
269        public static MergeWhenClauseProcessor createMergeWhenClauseProcessor(
270                        GFmtOpt option )
271        {
272                return (MergeWhenClauseProcessor) create( MergeWhenClauseProcessor.class,
273                                option );
274        }
275
276        /**
277         * create the processor used to capitalize the text
278         * 
279         * @param option
280         * @return
281         */
282        public static gudusoft.gsqlparser.pp.processor.type.comm.StatementIndentLevelProcessor createStatementIndentLevelProcessor(
283                        GFmtOpt opt )
284        {
285                return (gudusoft.gsqlparser.pp.processor.type.comm.StatementIndentLevelProcessor) create( gudusoft.gsqlparser.pp.processor.type.comm.StatementIndentLevelProcessor.class,
286                                opt );
287        }
288
289        public static CapitalisationProcessor createCapitalisationProcessor(
290                        GFmtOpt option )
291        {
292                return (CapitalisationProcessor) create( CapitalisationProcessor.class,
293                                option );
294        }
295
296        /**
297         * create the processor used to append new line before the keyword
298         * 
299         * @param option
300         * @param keyword
301         * @return
302         */
303        public static AppendNewLineBeforeReverseKeyWordProcessor createAppendNewLineBeforeReverseKeyWordProcessor(
304                        GFmtOpt option, boolean inNewLine, String keyword )
305        {
306                return (AppendNewLineBeforeReverseKeyWordProcessor) create( AppendNewLineBeforeReverseKeyWordProcessor.class,
307                                option,
308                                inNewLine,
309                                keyword );
310        }
311
312        /**
313         * create the processor used to adjust the left parenthesis
314         * 
315         * @param option
316         * @return
317         */
318        public static InsertValuesParenthsesAdjustProcessor createInsertValuesParenthsesAdjustProcessor(
319                        GFmtOpt option )
320        {
321                return (InsertValuesParenthsesAdjustProcessor) create( InsertValuesParenthsesAdjustProcessor.class,
322                                option );
323        }
324
325        /**
326         * create the processor used to align the keywords in the delete statement
327         * 
328         * @param option
329         * @return
330         */
331        public static DeleteKeyWordAlignProcessor createDeleteKeyWordAlignProcessor(
332                        GFmtOpt option )
333        {
334                return (DeleteKeyWordAlignProcessor) create( DeleteKeyWordAlignProcessor.class,
335                                option );
336
337        }
338
339        /**
340         * create the processor used to align the keywords in the update statement
341         * 
342         * @param option
343         * @return
344         */
345        public static UpdateKeyWordAlignProcessor createUpdateKeyWordAlignProcessor(
346                        GFmtOpt option )
347        {
348                return (UpdateKeyWordAlignProcessor) create( UpdateKeyWordAlignProcessor.class,
349                                option );
350        }
351
352        /**
353         * create the processor used to insert new line after the parenthesis
354         * 
355         * @param option
356         * @param leftBEOnNewline
357         * @param rightBeOnNewline
358         * @return
359         */
360        public static CreateTableBEInNewLineProcessor createCreateTableBEInNewLineProcessor(
361                        GFmtOpt option, Boolean leftBEOnNewline, Boolean rightBeOnNewline,
362                        Boolean itemListInNewLine )
363        {
364                return (CreateTableBEInNewLineProcessor) create( CreateTableBEInNewLineProcessor.class,
365                                option,
366                                leftBEOnNewline,
367                                rightBeOnNewline,
368                                itemListInNewLine );
369        }
370
371        /**
372         * create the processor used to align the items
373         * 
374         * @param option
375         * @param alignOption
376         * @return
377         */
378        public static CreateTableItemAlignProcessor createCreateTableItemAlignProcessor(
379                        GFmtOpt option, TAlignOption alignOption )
380        {
381                return (CreateTableItemAlignProcessor) create( CreateTableItemAlignProcessor.class,
382                                option,
383                                alignOption );
384        }
385
386        public static CTEProcessor createCTEProcessor( GFmtOpt option,
387                        Boolean cteNewlineBeforeAs )
388        {
389                return (CTEProcessor) create( CTEProcessor.class,
390                                option,
391                                cteNewlineBeforeAs );
392        }
393
394        /**
395         * used to align the variable names
396         * 
397         * @param option
398         * @return
399         */
400        public static DeclareVarItemAlignProcessor createDeclareVarItemAlignProcessor(
401                        GFmtOpt option )
402        {
403                return (DeclareVarItemAlignProcessor) create( DeclareVarItemAlignProcessor.class,
404                                option );
405        }
406
407        public static CreateTableConstraintAlignProcessor createCreateTableConstraintAlignProcessor(
408                        GFmtOpt option )
409        {
410                return (CreateTableConstraintAlignProcessor) create( CreateTableConstraintAlignProcessor.class,
411                                option );
412        }
413
414        public static CombineWhitespaceAndClearReturnProcessor createCombineWhitespaceAndClearReturnProcessor(
415                        GFmtOpt opt )
416        {
417                return (CombineWhitespaceAndClearReturnProcessor) create( CombineWhitespaceAndClearReturnProcessor.class,
418                                opt );
419        }
420
421        public static InsertOutputClauseProcessor createInsertOutputClauseProcessor(
422                        GFmtOpt opt )
423        {
424                return (InsertOutputClauseProcessor) create( InsertOutputClauseProcessor.class,
425                                opt );
426        }
427
428        public static ExecParaNewLineProcessor createExecParaNewLineProcessor(
429                        GFmtOpt opt, Boolean linebreakBeforeParamInExec )
430        {
431                return (ExecParaNewLineProcessor) create( ExecParaNewLineProcessor.class,
432                                opt,
433                                linebreakBeforeParamInExec );
434        }
435
436        public static CreateFuncLeftBEProcessor createCreateFuncLeftBEProcessor(
437                        GFmtOpt opt, Boolean beStyleFunctionLeftBEOnNewline,
438                        Integer beStyleFunctionLeftBEIndentSize )
439        {
440                return (CreateFuncLeftBEProcessor) create( CreateFuncLeftBEProcessor.class,
441                                opt,
442                                beStyleFunctionLeftBEOnNewline,
443                                beStyleFunctionLeftBEIndentSize );
444        }
445
446        public static CreateFuncRightBEProcessor createCreateFuncRightBEProcessor(
447                        GFmtOpt opt, Boolean beStyleFunctionRightBEOnNewline,
448                        Integer beStyleFunctionRightBEIndentSize )
449        {
450                return (CreateFuncRightBEProcessor) create( CreateFuncRightBEProcessor.class,
451                                opt,
452                                beStyleFunctionRightBEOnNewline,
453                                beStyleFunctionRightBEIndentSize );
454        }
455
456        public static CreateFuncFirstParamInNewlineProcessor createCreateFuncFirstParamInNewlineProcessor(
457                        GFmtOpt opt, Boolean beStyleFunctionFirstParamInNewline )
458        {
459                return (CreateFuncFirstParamInNewlineProcessor) create( CreateFuncFirstParamInNewlineProcessor.class,
460                                opt,
461                                beStyleFunctionFirstParamInNewline );
462        }
463
464        public static CreateFuncReturnsTableProcessor createCreateFuncReturnsTableProcessor(
465                        GFmtOpt opt )
466        {
467                return (CreateFuncReturnsTableProcessor) create( CreateFuncReturnsTableProcessor.class,
468                                opt );
469        }
470
471        public static CreateFuncWSPaddingParenthesesProcessor createCreateFuncWSPaddingParenthesesProcessor(
472                        GFmtOpt opt )
473        {
474                return (CreateFuncWSPaddingParenthesesProcessor) create( CreateFuncWSPaddingParenthesesProcessor.class,
475                                opt );
476        }
477
478        public static IfStmtBEProcessor createIfStmtBEProcessor( GFmtOpt opt )
479        {
480                return (IfStmtBEProcessor) create( IfStmtBEProcessor.class, opt );
481        }
482
483        public static ReturnStmtProcessor createReturnStmtProcessor( GFmtOpt opt )
484        {
485                return (ReturnStmtProcessor) create( ReturnStmtProcessor.class, opt );
486        }
487
488        public static gudusoft.gsqlparser.pp.processor.type.createtable.CreateTableAsProcessor createCreateTableAsProcessor(
489                        GFmtOpt opt )
490        {
491                return (gudusoft.gsqlparser.pp.processor.type.createtable.CreateTableAsProcessor) create( gudusoft.gsqlparser.pp.processor.type.createtable.CreateTableAsProcessor.class,
492                                opt );
493        }
494
495        public static gudusoft.gsqlparser.pp.processor.type.createview.CreateMaterializedViewReturnProcessor createCreateMaterializedViewReturnProcessor(
496                        GFmtOpt opt )
497        {
498                return (gudusoft.gsqlparser.pp.processor.type.createview.CreateMaterializedViewReturnProcessor) create( gudusoft.gsqlparser.pp.processor.type.createview.CreateMaterializedViewReturnProcessor.class,
499                                opt );
500        }
501
502        public static CreateViewReturnProcessor createCreateViewReturnProcessor(
503                        GFmtOpt opt )
504        {
505                return (CreateViewReturnProcessor) create( CreateViewReturnProcessor.class,
506                                opt );
507        }
508
509        public static AlterTableOptionItemAlignProcessor createAlterTableOptionAlignProcessor(
510                        GFmtOpt option, boolean inNewLine )
511        {
512                return (AlterTableOptionItemAlignProcessor) create( AlterTableOptionItemAlignProcessor.class,
513                                option,
514                                inNewLine );
515        }
516
517        public static AppendNewLineBeforeKeyWordProcessor createAppendNewLineBeforeKeyWordProcessor(
518                        GFmtOpt option, boolean inNewLine, String keyword,
519                        boolean completely )
520        {
521                return (AppendNewLineBeforeKeyWordProcessor) create( AppendNewLineBeforeKeyWordProcessor.class,
522                                option,
523                                inNewLine,
524                                keyword,
525                                completely );
526        }
527
528        /**
529         * create a instance
530         * 
531         * @param type
532         * @return
533         */
534        public static <E extends AbstractProcessor> E create( Class<E> type,
535                        GFmtOpt option, Object... parameters )
536        {
537                if ( !AbstractProcessor.class.isAssignableFrom( type ) )
538                {
539                        return null;
540                }
541
542                StringBuilder idBuf = new StringBuilder( );
543                idBuf.append( option.sessionId ).append( ":" );
544                idBuf.append( type.getName( ) ).append( ":" );
545                if ( parameters != null )
546                {
547                        for ( Object obj : parameters )
548                        {
549                                idBuf.append( obj != null ? obj.toString( ) : ":" );
550                        }
551                }
552
553                if ( !processors.containsKey( idBuf.toString( ) ) )
554                {
555                        synchronized ( ProcessorFactory.class )
556                        {
557                                if ( !processors.containsKey( idBuf.toString( ) ) )
558                                {
559                                        E processor = newInstance( type );
560                                        processor.init( option, parameters );
561                                        processors.put( idBuf.toString( ), processor );
562                                }
563                        }
564                }
565
566                return (E) processors.get( idBuf.toString( ) );
567
568        }
569
570        /**
571         * create a new processor instance
572         * 
573         * @param type
574         *            the processor type
575         * @return insteance
576         */
577        public static <E extends AbstractProcessor> E newInstance( Class<E> type )
578        {
579                try
580                {
581                        return (E) type.newInstance( );
582                }
583                catch ( InstantiationException e )
584                {
585                        PPLogger.error( e );
586                        return null;
587                }
588                catch ( IllegalAccessException e )
589                {
590                        PPLogger.error( e );
591                        return null;
592                }
593        }
594
595        public static void clear( String sessionId )
596        {
597                synchronized ( object )
598                {
599                        List<String> removedKeys = new ArrayList<String>( );
600                        for ( String key : processors.keySet( ) )
601                        {
602                                if ( key.startsWith( sessionId ) )
603                                {
604                                        removedKeys.add( key );
605                                }
606                        }
607                        for ( String key : removedKeys )
608                        {
609                                processors.remove( key );
610                        }
611                }
612        }
613
614        public static AbstractProcessor<TStatementList> createStmtListProcessor(
615                        GFmtOpt opt, String alignKeyword )
616        {
617                return (StmtListProcessor) create( StmtListProcessor.class,
618                                opt,
619                                alignKeyword );
620        }
621
622        public static AbstractProcessor<TBlockSqlStatement> createBeginAndEndProcessor(
623                        GFmtOpt opt )
624        {
625                return (BeginAndEndProcessor) create( BeginAndEndProcessor.class, opt );
626        }
627
628        public static AbstractProcessor<TIfStmt> createPlsqlIfStmtBEProcessor(
629                        GFmtOpt opt )
630        {
631                return (PlsqlIfStmtBEProcessor) create( PlsqlIfStmtBEProcessor.class,
632                                opt );
633        }
634}