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 CapitalisationProcessor createCapitalisationProcessor(
283                        GFmtOpt option )
284        {
285                return (CapitalisationProcessor) create( CapitalisationProcessor.class,
286                                option );
287        }
288
289        /**
290         * create the processor used to append new line before the keyword
291         * 
292         * @param option
293         * @param keyword
294         * @return
295         */
296        public static AppendNewLineBeforeReverseKeyWordProcessor createAppendNewLineBeforeReverseKeyWordProcessor(
297                        GFmtOpt option, boolean inNewLine, String keyword )
298        {
299                return (AppendNewLineBeforeReverseKeyWordProcessor) create( AppendNewLineBeforeReverseKeyWordProcessor.class,
300                                option,
301                                inNewLine,
302                                keyword );
303        }
304
305        /**
306         * create the processor used to adjust the left parenthesis
307         * 
308         * @param option
309         * @return
310         */
311        public static InsertValuesParenthsesAdjustProcessor createInsertValuesParenthsesAdjustProcessor(
312                        GFmtOpt option )
313        {
314                return (InsertValuesParenthsesAdjustProcessor) create( InsertValuesParenthsesAdjustProcessor.class,
315                                option );
316        }
317
318        /**
319         * create the processor used to align the keywords in the delete statement
320         * 
321         * @param option
322         * @return
323         */
324        public static DeleteKeyWordAlignProcessor createDeleteKeyWordAlignProcessor(
325                        GFmtOpt option )
326        {
327                return (DeleteKeyWordAlignProcessor) create( DeleteKeyWordAlignProcessor.class,
328                                option );
329
330        }
331
332        /**
333         * create the processor used to align the keywords in the update statement
334         * 
335         * @param option
336         * @return
337         */
338        public static UpdateKeyWordAlignProcessor createUpdateKeyWordAlignProcessor(
339                        GFmtOpt option )
340        {
341                return (UpdateKeyWordAlignProcessor) create( UpdateKeyWordAlignProcessor.class,
342                                option );
343        }
344
345        /**
346         * create the processor used to insert new line after the parenthesis
347         * 
348         * @param option
349         * @param leftBEOnNewline
350         * @param rightBeOnNewline
351         * @return
352         */
353        public static CreateTableBEInNewLineProcessor createCreateTableBEInNewLineProcessor(
354                        GFmtOpt option, Boolean leftBEOnNewline, Boolean rightBeOnNewline,
355                        Boolean itemListInNewLine )
356        {
357                return (CreateTableBEInNewLineProcessor) create( CreateTableBEInNewLineProcessor.class,
358                                option,
359                                leftBEOnNewline,
360                                rightBeOnNewline,
361                                itemListInNewLine );
362        }
363
364        /**
365         * create the processor used to align the items
366         * 
367         * @param option
368         * @param alignOption
369         * @return
370         */
371        public static CreateTableItemAlignProcessor createCreateTableItemAlignProcessor(
372                        GFmtOpt option, TAlignOption alignOption )
373        {
374                return (CreateTableItemAlignProcessor) create( CreateTableItemAlignProcessor.class,
375                                option,
376                                alignOption );
377        }
378
379        public static CTEProcessor createCTEProcessor( GFmtOpt option,
380                        Boolean cteNewlineBeforeAs )
381        {
382                return (CTEProcessor) create( CTEProcessor.class,
383                                option,
384                                cteNewlineBeforeAs );
385        }
386
387        /**
388         * used to align the variable names
389         * 
390         * @param option
391         * @return
392         */
393        public static DeclareVarItemAlignProcessor createDeclareVarItemAlignProcessor(
394                        GFmtOpt option )
395        {
396                return (DeclareVarItemAlignProcessor) create( DeclareVarItemAlignProcessor.class,
397                                option );
398        }
399
400        public static CreateTableConstraintAlignProcessor createCreateTableConstraintAlignProcessor(
401                        GFmtOpt option )
402        {
403                return (CreateTableConstraintAlignProcessor) create( CreateTableConstraintAlignProcessor.class,
404                                option );
405        }
406
407        public static CombineWhitespaceAndClearReturnProcessor createCombineWhitespaceAndClearReturnProcessor(
408                        GFmtOpt opt )
409        {
410                return (CombineWhitespaceAndClearReturnProcessor) create( CombineWhitespaceAndClearReturnProcessor.class,
411                                opt );
412        }
413
414        public static InsertOutputClauseProcessor createInsertOutputClauseProcessor(
415                        GFmtOpt opt )
416        {
417                return (InsertOutputClauseProcessor) create( InsertOutputClauseProcessor.class,
418                                opt );
419        }
420
421        public static ExecParaNewLineProcessor createExecParaNewLineProcessor(
422                        GFmtOpt opt, Boolean linebreakBeforeParamInExec )
423        {
424                return (ExecParaNewLineProcessor) create( ExecParaNewLineProcessor.class,
425                                opt,
426                                linebreakBeforeParamInExec );
427        }
428
429        public static CreateFuncLeftBEProcessor createCreateFuncLeftBEProcessor(
430                        GFmtOpt opt, Boolean beStyleFunctionLeftBEOnNewline,
431                        Integer beStyleFunctionLeftBEIndentSize )
432        {
433                return (CreateFuncLeftBEProcessor) create( CreateFuncLeftBEProcessor.class,
434                                opt,
435                                beStyleFunctionLeftBEOnNewline,
436                                beStyleFunctionLeftBEIndentSize );
437        }
438
439        public static CreateFuncRightBEProcessor createCreateFuncRightBEProcessor(
440                        GFmtOpt opt, Boolean beStyleFunctionRightBEOnNewline,
441                        Integer beStyleFunctionRightBEIndentSize )
442        {
443                return (CreateFuncRightBEProcessor) create( CreateFuncRightBEProcessor.class,
444                                opt,
445                                beStyleFunctionRightBEOnNewline,
446                                beStyleFunctionRightBEIndentSize );
447        }
448
449        public static CreateFuncFirstParamInNewlineProcessor createCreateFuncFirstParamInNewlineProcessor(
450                        GFmtOpt opt, Boolean beStyleFunctionFirstParamInNewline )
451        {
452                return (CreateFuncFirstParamInNewlineProcessor) create( CreateFuncFirstParamInNewlineProcessor.class,
453                                opt,
454                                beStyleFunctionFirstParamInNewline );
455        }
456
457        public static CreateFuncReturnsTableProcessor createCreateFuncReturnsTableProcessor(
458                        GFmtOpt opt )
459        {
460                return (CreateFuncReturnsTableProcessor) create( CreateFuncReturnsTableProcessor.class,
461                                opt );
462        }
463
464        public static CreateFuncWSPaddingParenthesesProcessor createCreateFuncWSPaddingParenthesesProcessor(
465                        GFmtOpt opt )
466        {
467                return (CreateFuncWSPaddingParenthesesProcessor) create( CreateFuncWSPaddingParenthesesProcessor.class,
468                                opt );
469        }
470
471        public static IfStmtBEProcessor createIfStmtBEProcessor( GFmtOpt opt )
472        {
473                return (IfStmtBEProcessor) create( IfStmtBEProcessor.class, opt );
474        }
475
476        public static ReturnStmtProcessor createReturnStmtProcessor( GFmtOpt opt )
477        {
478                return (ReturnStmtProcessor) create( ReturnStmtProcessor.class, opt );
479        }
480
481        public static CreateViewReturnProcessor createCreateViewReturnProcessor(
482                        GFmtOpt opt )
483        {
484                return (CreateViewReturnProcessor) create( CreateViewReturnProcessor.class,
485                                opt );
486        }
487
488        public static AlterTableOptionItemAlignProcessor createAlterTableOptionAlignProcessor(
489                        GFmtOpt option, boolean inNewLine )
490        {
491                return (AlterTableOptionItemAlignProcessor) create( AlterTableOptionItemAlignProcessor.class,
492                                option,
493                                inNewLine );
494        }
495
496        public static AppendNewLineBeforeKeyWordProcessor createAppendNewLineBeforeKeyWordProcessor(
497                        GFmtOpt option, boolean inNewLine, String keyword,
498                        boolean completely )
499        {
500                return (AppendNewLineBeforeKeyWordProcessor) create( AppendNewLineBeforeKeyWordProcessor.class,
501                                option,
502                                inNewLine,
503                                keyword,
504                                completely );
505        }
506
507        /**
508         * create a instance
509         * 
510         * @param type
511         * @return
512         */
513        public static <E extends AbstractProcessor> E create( Class<E> type,
514                        GFmtOpt option, Object... parameters )
515        {
516                if ( !AbstractProcessor.class.isAssignableFrom( type ) )
517                {
518                        return null;
519                }
520
521                StringBuilder idBuf = new StringBuilder( );
522                idBuf.append( option.sessionId ).append( ":" );
523                idBuf.append( type.getName( ) ).append( ":" );
524                if ( parameters != null )
525                {
526                        for ( Object obj : parameters )
527                        {
528                                idBuf.append( obj != null ? obj.toString( ) : ":" );
529                        }
530                }
531
532                if ( !processors.containsKey( idBuf.toString( ) ) )
533                {
534                        synchronized ( ProcessorFactory.class )
535                        {
536                                if ( !processors.containsKey( idBuf.toString( ) ) )
537                                {
538                                        E processor = newInstance( type );
539                                        processor.init( option, parameters );
540                                        processors.put( idBuf.toString( ), processor );
541                                }
542                        }
543                }
544
545                return (E) processors.get( idBuf.toString( ) );
546
547        }
548
549        /**
550         * create a new processor instance
551         * 
552         * @param type
553         *            the processor type
554         * @return insteance
555         */
556        public static <E extends AbstractProcessor> E newInstance( Class<E> type )
557        {
558                try
559                {
560                        return (E) type.newInstance( );
561                }
562                catch ( InstantiationException e )
563                {
564                        PPLogger.error( e );
565                        return null;
566                }
567                catch ( IllegalAccessException e )
568                {
569                        PPLogger.error( e );
570                        return null;
571                }
572        }
573
574        public static void clear( String sessionId )
575        {
576                synchronized ( object )
577                {
578                        List<String> removedKeys = new ArrayList<String>( );
579                        for ( String key : processors.keySet( ) )
580                        {
581                                if ( key.startsWith( sessionId ) )
582                                {
583                                        removedKeys.add( key );
584                                }
585                        }
586                        for ( String key : removedKeys )
587                        {
588                                processors.remove( key );
589                        }
590                }
591        }
592
593        public static AbstractProcessor<TStatementList> createStmtListProcessor(
594                        GFmtOpt opt, String alignKeyword )
595        {
596                return (StmtListProcessor) create( StmtListProcessor.class,
597                                opt,
598                                alignKeyword );
599        }
600
601        public static AbstractProcessor<TBlockSqlStatement> createBeginAndEndProcessor(
602                        GFmtOpt opt )
603        {
604                return (BeginAndEndProcessor) create( BeginAndEndProcessor.class, opt );
605        }
606
607        public static AbstractProcessor<TIfStmt> createPlsqlIfStmtBEProcessor(
608                        GFmtOpt opt )
609        {
610                return (PlsqlIfStmtBEProcessor) create( PlsqlIfStmtBEProcessor.class,
611                                opt );
612        }
613}