001 002package gudusoft.gsqlparser.pp.stmtformatter; 003 004import gudusoft.gsqlparser.TCustomSqlStatement; 005import gudusoft.gsqlparser.TGSqlParser; 006import gudusoft.gsqlparser.TSourceToken; 007import gudusoft.gsqlparser.TSourceTokenList; 008import gudusoft.gsqlparser.TStatementList; 009import gudusoft.gsqlparser.pp.mediator.MediatorFactory; 010import gudusoft.gsqlparser.pp.output.OutputConfig; 011import gudusoft.gsqlparser.pp.output.OutputConfigFactory; 012import gudusoft.gsqlparser.pp.para.GFmtOpt; 013import gudusoft.gsqlparser.pp.para.styleenums.TCompactMode; 014import gudusoft.gsqlparser.pp.print.IPrinter; 015import gudusoft.gsqlparser.pp.print.PrinterFactory; 016import gudusoft.gsqlparser.pp.processor.ProcessorFactory; 017import gudusoft.gsqlparser.pp.stmtformatter.builder.AbstractStmtFormatterBuilder; 018import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.AllStmtsFormatterBuilder; 019import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.AlterTableStmtFormatterBuilder; 020import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.CommonStmtFormatterBuilder; 021import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.CompactModeStmtFormatterBuilder; 022import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.CreateTableStmtFormatterBuilder; 023import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.CreateViewStmtFormatterBuilder; 024import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.DeclareStmtFormatterBuilder; 025import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.DeleteStmtFormatterBuilder; 026import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.ExecuteStmtFormatterBuilder; 027import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.GoStmtFormatterBuilder; 028import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.IfStmtFormatterBuilder; 029import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.InsertStmtFormatterBuilder; 030import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.MergeStmtFormatterBuilder; 031import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.PlsqlBlockStmtFormatterBuilder; 032import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.PlsqlIfStmtFormatterBuilder; 033import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.PlsqlStmtFormatterBuilder; 034import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.ReturnStmtFormatterBuilder; 035import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.SelectStmtFormatterBuilder; 036import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.SetStmtFormatterBuilder; 037import gudusoft.gsqlparser.pp.stmtformatter.builder.comm.UpdateStmtFormatterBuilder; 038import gudusoft.gsqlparser.pp.stmtformatter.type.AbstractStmtFormatter; 039import gudusoft.gsqlparser.pp.stmtformatter.type.comm.AllStmtsFormatter; 040import gudusoft.gsqlparser.pp.stmtformatter.type.comm.AlterTableStmtFormatter; 041import gudusoft.gsqlparser.pp.stmtformatter.type.comm.CommonStmtFormatter; 042import gudusoft.gsqlparser.pp.stmtformatter.type.comm.CompactModeStmtFormatter; 043import gudusoft.gsqlparser.pp.stmtformatter.type.comm.CreateTableStmtFormatter; 044import gudusoft.gsqlparser.pp.stmtformatter.type.comm.CreateViewStmtFormatter; 045import gudusoft.gsqlparser.pp.stmtformatter.type.comm.DeclareStmtFormatter; 046import gudusoft.gsqlparser.pp.stmtformatter.type.comm.DeleteStmtFormatter; 047import gudusoft.gsqlparser.pp.stmtformatter.type.comm.ExecuteStmtFormatter; 048import gudusoft.gsqlparser.pp.stmtformatter.type.comm.GoStmtFormatter; 049import gudusoft.gsqlparser.pp.stmtformatter.type.comm.IfStmtFormatter; 050import gudusoft.gsqlparser.pp.stmtformatter.type.comm.InsertStmtFormatter; 051import gudusoft.gsqlparser.pp.stmtformatter.type.comm.MergeStmtFormatter; 052import gudusoft.gsqlparser.pp.stmtformatter.type.comm.PlsqlBlockStmtFormatter; 053import gudusoft.gsqlparser.pp.stmtformatter.type.comm.PlsqlIfStmtFormatter; 054import gudusoft.gsqlparser.pp.stmtformatter.type.comm.PlsqlStmtFormatter; 055import gudusoft.gsqlparser.pp.stmtformatter.type.comm.ReturnStmtFormatter; 056import gudusoft.gsqlparser.pp.stmtformatter.type.comm.SelectStmtFormatter; 057import gudusoft.gsqlparser.pp.stmtformatter.type.comm.SetStmtFormatter; 058import gudusoft.gsqlparser.pp.stmtformatter.type.comm.UpdateStmtFormatter; 059import gudusoft.gsqlparser.pp.utils.SourceTokenOperator; 060import gudusoft.gsqlparser.stmt.TAlterTableStatement; 061import gudusoft.gsqlparser.stmt.TCommonBlock; 062import gudusoft.gsqlparser.stmt.TCreateTableSqlStatement; 063import gudusoft.gsqlparser.stmt.TCreateViewSqlStatement; 064import gudusoft.gsqlparser.stmt.TDeleteSqlStatement; 065import gudusoft.gsqlparser.stmt.TIfStmt; 066import gudusoft.gsqlparser.stmt.TInsertSqlStatement; 067import gudusoft.gsqlparser.stmt.TMergeSqlStatement; 068import gudusoft.gsqlparser.stmt.TSelectSqlStatement; 069import gudusoft.gsqlparser.stmt.TStoredProcedureSqlStatement; 070import gudusoft.gsqlparser.stmt.TUpdateSqlStatement; 071import gudusoft.gsqlparser.stmt.mssql.TMssqlBlock; 072import gudusoft.gsqlparser.stmt.mssql.TMssqlDeclare; 073import gudusoft.gsqlparser.stmt.mssql.TMssqlExecute; 074import gudusoft.gsqlparser.stmt.mssql.TMssqlGo; 075import gudusoft.gsqlparser.stmt.mssql.TMssqlIfElse; 076import gudusoft.gsqlparser.stmt.mssql.TMssqlReturn; 077import gudusoft.gsqlparser.stmt.mssql.TMssqlSet; 078import gudusoft.gsqlparser.pp2.Pp2FormatOptions; 079import gudusoft.gsqlparser.pp2.Pp2FormatResult; 080import gudusoft.gsqlparser.pp2.engine.Pp2Engine; 081 082import java.io.ByteArrayOutputStream; 083import java.io.OutputStream; 084import java.util.ArrayList; 085import java.util.List; 086import java.util.Map; 087import java.util.concurrent.ConcurrentHashMap; 088 089public class FormatterFactory 090{ 091 092 /** 093 * all formatters 094 */ 095 private volatile static Map<String, AbstractStmtFormatter> formatter = new ConcurrentHashMap<String, AbstractStmtFormatter>( ); 096 097 private static Object object = new Object( ); 098 099 private static OutputConfig outputConfig; 100 101 /** 102 * create select statment formatter 103 * 104 * @param opt 105 * options 106 * @return instance 107 */ 108 public static SelectStmtFormatter createSelectStmtFormatter( GFmtOpt opt ) 109 { 110 return createFormatter( opt, 111 SelectStmtFormatter.class, 112 new IFormatterBuilderCreator<SelectStmtFormatter>( ) { 113 114 public AbstractStmtFormatterBuilder<SelectStmtFormatter> create( ) 115 { 116 return new SelectStmtFormatterBuilder( ); 117 } 118 } ); 119 } 120 121 public static InsertStmtFormatter createInsertStmtFormatter( GFmtOpt opt ) 122 { 123 return createFormatter( opt, 124 InsertStmtFormatter.class, 125 new IFormatterBuilderCreator<InsertStmtFormatter>( ) { 126 127 public AbstractStmtFormatterBuilder<InsertStmtFormatter> create( ) 128 { 129 return new InsertStmtFormatterBuilder( ); 130 } 131 } ); 132 } 133 134 public static DeleteStmtFormatter createDeleteStmtFormatter( GFmtOpt opt ) 135 { 136 return createFormatter( opt, 137 DeleteStmtFormatter.class, 138 new IFormatterBuilderCreator<DeleteStmtFormatter>( ) { 139 140 public AbstractStmtFormatterBuilder<DeleteStmtFormatter> create( ) 141 { 142 return new DeleteStmtFormatterBuilder( ); 143 } 144 } ); 145 } 146 147 public static UpdateStmtFormatter createUpdateStmtFormatter( GFmtOpt opt ) 148 { 149 return createFormatter( opt, 150 UpdateStmtFormatter.class, 151 new IFormatterBuilderCreator<UpdateStmtFormatter>( ) { 152 153 public AbstractStmtFormatterBuilder<UpdateStmtFormatter> create( ) 154 { 155 return new UpdateStmtFormatterBuilder( ); 156 } 157 } ); 158 } 159 160 public static CreateTableStmtFormatter createCreateTableStmtFormatter( 161 GFmtOpt opt ) 162 { 163 return createFormatter( opt, 164 CreateTableStmtFormatter.class, 165 new IFormatterBuilderCreator<CreateTableStmtFormatter>( ) { 166 167 public AbstractStmtFormatterBuilder<CreateTableStmtFormatter> create( ) 168 { 169 return new CreateTableStmtFormatterBuilder( ); 170 } 171 } ); 172 } 173 174 public static DeclareStmtFormatter createDeclareStmtFormatter( GFmtOpt opt ) 175 { 176 return createFormatter( opt, 177 DeclareStmtFormatter.class, 178 new IFormatterBuilderCreator<DeclareStmtFormatter>( ) { 179 180 public AbstractStmtFormatterBuilder<DeclareStmtFormatter> create( ) 181 { 182 return new DeclareStmtFormatterBuilder( ); 183 } 184 } ); 185 } 186 187 public static ExecuteStmtFormatter createExecuteStmtFormatter( GFmtOpt opt ) 188 { 189 return createFormatter( opt, 190 ExecuteStmtFormatter.class, 191 new IFormatterBuilderCreator<ExecuteStmtFormatter>( ) { 192 193 public AbstractStmtFormatterBuilder<ExecuteStmtFormatter> create( ) 194 { 195 return new ExecuteStmtFormatterBuilder( ); 196 } 197 } ); 198 } 199 200 public static SetStmtFormatter createSetStmtFormatter( GFmtOpt opt ) 201 { 202 return createFormatter( opt, 203 SetStmtFormatter.class, 204 new IFormatterBuilderCreator<SetStmtFormatter>( ) { 205 206 public AbstractStmtFormatterBuilder<SetStmtFormatter> create( ) 207 { 208 return new SetStmtFormatterBuilder( ); 209 } 210 } ); 211 } 212 213 public static IfStmtFormatter createIfStmtFormatter( GFmtOpt opt ) 214 { 215 return createFormatter( opt, 216 IfStmtFormatter.class, 217 new IFormatterBuilderCreator<IfStmtFormatter>( ) { 218 219 public AbstractStmtFormatterBuilder<IfStmtFormatter> create( ) 220 { 221 return new IfStmtFormatterBuilder( ); 222 } 223 } ); 224 } 225 226 public static PlsqlIfStmtFormatter createPlsqlIfStmtFormatter( GFmtOpt opt ) 227 { 228 return createFormatter( opt, 229 PlsqlIfStmtFormatter.class, 230 new IFormatterBuilderCreator<PlsqlIfStmtFormatter>( ) { 231 232 public AbstractStmtFormatterBuilder<PlsqlIfStmtFormatter> create( ) 233 { 234 return new PlsqlIfStmtFormatterBuilder( ); 235 } 236 } ); 237 } 238 239 public static PlsqlStmtFormatter createPlsqlStmtFormatter( GFmtOpt opt ) 240 { 241 return createFormatter( opt, 242 PlsqlStmtFormatter.class, 243 new IFormatterBuilderCreator<PlsqlStmtFormatter>( ) { 244 245 public AbstractStmtFormatterBuilder<PlsqlStmtFormatter> create( ) 246 { 247 return new PlsqlStmtFormatterBuilder( ); 248 } 249 } ); 250 } 251 252 public static GoStmtFormatter createGoStmtFormatter( GFmtOpt opt ) 253 { 254 return createFormatter( opt, 255 GoStmtFormatter.class, 256 new IFormatterBuilderCreator<GoStmtFormatter>( ) { 257 258 public AbstractStmtFormatterBuilder<GoStmtFormatter> create( ) 259 { 260 return new GoStmtFormatterBuilder( ); 261 } 262 } ); 263 } 264 265 public static CompactModeStmtFormatter createCompactModeStmtFormatter( 266 GFmtOpt opt ) 267 { 268 return createFormatter( opt, 269 CompactModeStmtFormatter.class, 270 new IFormatterBuilderCreator<CompactModeStmtFormatter>( ) { 271 272 public AbstractStmtFormatterBuilder<CompactModeStmtFormatter> create( ) 273 { 274 return new CompactModeStmtFormatterBuilder( ); 275 } 276 } ); 277 } 278 279 public static ReturnStmtFormatter createReturnStmtFormatter( GFmtOpt opt ) 280 { 281 return createFormatter( opt, 282 ReturnStmtFormatter.class, 283 new IFormatterBuilderCreator<ReturnStmtFormatter>( ) { 284 285 public AbstractStmtFormatterBuilder<ReturnStmtFormatter> create( ) 286 { 287 return new ReturnStmtFormatterBuilder( ); 288 } 289 } ); 290 } 291 292 public static CreateViewStmtFormatter createCreateViewStmtFormatter( 293 GFmtOpt opt ) 294 { 295 return createFormatter( opt, 296 CreateViewStmtFormatter.class, 297 new IFormatterBuilderCreator<CreateViewStmtFormatter>( ) { 298 299 public AbstractStmtFormatterBuilder<CreateViewStmtFormatter> create( ) 300 { 301 return new CreateViewStmtFormatterBuilder( ); 302 } 303 } ); 304 } 305 306 public static AlterTableStmtFormatter createAlterTableStatement( GFmtOpt opt ) 307 { 308 return createFormatter( opt, 309 AlterTableStmtFormatter.class, 310 new IFormatterBuilderCreator<AlterTableStmtFormatter>( ) { 311 312 public AbstractStmtFormatterBuilder<AlterTableStmtFormatter> create( ) 313 { 314 return new AlterTableStmtFormatterBuilder( ); 315 } 316 } ); 317 } 318 319 /** 320 * the callback interface to achieve the formatter builder 321 * 322 * @author zhoujun 323 * 324 */ 325 public interface IFormatterBuilderCreator<E extends AbstractStmtFormatter> 326 { 327 328 AbstractStmtFormatterBuilder<E> create( ); 329 } 330 331 /** 332 * create the formatter 333 * 334 * @param <E> 335 * @param opt 336 * @param clazz 337 * @param creater 338 * @return 339 */ 340 public static <E extends AbstractStmtFormatter> E createFormatter( 341 GFmtOpt opt, Class<E> clazz, IFormatterBuilderCreator<E> creater ) 342 { 343 String id = opt.sessionId + clazz.getName( ); 344 if ( !formatter.containsKey( id ) ) 345 { 346 synchronized ( FormatterFactory.class ) 347 { 348 if ( !formatter.containsKey( id ) ) 349 { 350 AbstractStmtFormatterBuilder builder = creater.create( ); 351 builder.setOption( opt ); 352 formatter.put( id, builder.build( ) ); 353 } 354 } 355 } 356 return (E) formatter.get( id ); 357 } 358 359 public static void processStatement( GFmtOpt option, TCustomSqlStatement sql ) 360 { 361 if ( option.compactMode == TCompactMode.Cpmugly ) 362 { 363 FormatterFactory.createCompactModeStmtFormatter( option ) 364 .format( sql ); 365 return; 366 } 367 368 if ( isNotNeedFormat( sql ) ) 369 { 370 return; 371 } 372 if ( sql instanceof TSelectSqlStatement ) 373 { 374 FormatterFactory.createSelectStmtFormatter( option ) 375 .format( (TSelectSqlStatement) sql ); 376 } 377 else if ( sql instanceof TInsertSqlStatement ) 378 { 379 FormatterFactory.createInsertStmtFormatter( option ) 380 .format( (TInsertSqlStatement) sql ); 381 } 382 else if ( sql instanceof TDeleteSqlStatement ) 383 { 384 FormatterFactory.createDeleteStmtFormatter( option ) 385 .format( (TDeleteSqlStatement) sql ); 386 } 387 else if ( sql instanceof TUpdateSqlStatement ) 388 { 389 FormatterFactory.createUpdateStmtFormatter( option ) 390 .format( (TUpdateSqlStatement) sql ); 391 } 392 else if ( sql instanceof TCreateTableSqlStatement ) 393 { 394 FormatterFactory.createCreateTableStmtFormatter( option ) 395 .format( (TCreateTableSqlStatement) sql ); 396 } 397 else if ( sql instanceof TMssqlDeclare ) 398 { 399 FormatterFactory.createDeclareStmtFormatter( option ) 400 .format( (TMssqlDeclare) sql ); 401 } 402 else if ( sql instanceof TMssqlExecute ) 403 { 404 FormatterFactory.createExecuteStmtFormatter( option ) 405 .format( (TMssqlExecute) sql ); 406 } 407 else if ( sql instanceof TStoredProcedureSqlStatement ) 408 { 409 FormatterFactory.createPlsqlStmtFormatter( option ) 410 .format( (TStoredProcedureSqlStatement) sql ); 411 } 412 else if ( sql instanceof TMssqlSet ) 413 { 414 FormatterFactory.createSetStmtFormatter( option ) 415 .format( (TMssqlSet) sql ); 416 } 417 else if ( sql instanceof TMssqlIfElse ) 418 { 419 FormatterFactory.createIfStmtFormatter( option ) 420 .format( (TMssqlIfElse) sql ); 421 } 422 else if ( sql instanceof TMssqlGo ) 423 { 424 FormatterFactory.createGoStmtFormatter( option ) 425 .format( (TMssqlGo) sql ); 426 } 427 else if ( sql instanceof TMssqlReturn ) 428 { 429 FormatterFactory.createReturnStmtFormatter( option ) 430 .format( (TMssqlReturn) sql ); 431 } 432 else if ( sql instanceof TCreateViewSqlStatement ) 433 { 434 FormatterFactory.createCreateViewStmtFormatter( option ) 435 .format( (TCreateViewSqlStatement) sql ); 436 } 437 else if ( sql instanceof TAlterTableStatement ) 438 { 439 FormatterFactory.createAlterTableStatement( option ) 440 .format( (TAlterTableStatement) sql ); 441 } 442 else if ( sql instanceof TMergeSqlStatement ) 443 { 444 FormatterFactory.createMergeSqlStatement( option ) 445 .format( (TMergeSqlStatement) sql ); 446 } 447 else if ( sql instanceof TIfStmt ) 448 { 449 FormatterFactory.createPlsqlIfStmtFormatter( option ) 450 .format( (TIfStmt) sql ); 451 } 452 else 453 { 454 FormatterFactory.createCommonStatement( option ).format( sql ); 455 } 456 } 457 458 private static AbstractStmtFormatter<TCommonBlock> createPlsqlBlockStmtFormatter( 459 GFmtOpt opt ) 460 { 461 return createFormatter( opt, 462 PlsqlBlockStmtFormatter.class, 463 new IFormatterBuilderCreator<PlsqlBlockStmtFormatter>( ) { 464 465 public AbstractStmtFormatterBuilder<PlsqlBlockStmtFormatter> create( ) 466 { 467 return new PlsqlBlockStmtFormatterBuilder( ); 468 } 469 } ); 470 } 471 472 private static MergeStmtFormatter createMergeSqlStatement( GFmtOpt opt ) 473 { 474 return createFormatter( opt, 475 MergeStmtFormatter.class, 476 new IFormatterBuilderCreator<MergeStmtFormatter>( ) { 477 478 public AbstractStmtFormatterBuilder<MergeStmtFormatter> create( ) 479 { 480 return new MergeStmtFormatterBuilder( ); 481 } 482 } ); 483 } 484 485 private static CommonStmtFormatter createCommonStatement( GFmtOpt opt ) 486 { 487 return createFormatter( opt, 488 CommonStmtFormatter.class, 489 new IFormatterBuilderCreator<CommonStmtFormatter>( ) { 490 491 public AbstractStmtFormatterBuilder<CommonStmtFormatter> create( ) 492 { 493 return new CommonStmtFormatterBuilder( ); 494 } 495 } ); 496 } 497 498 public static boolean isNotNeedFormat( TCustomSqlStatement sql ) 499 { 500 if ( sql == null ) 501 { 502 // the null statement needn't formatting. 503 return true; 504 } 505 if ( sql.getStartToken( ) != null ) 506 { 507 TSourceToken t = sql.getStartToken( ); 508 return isNotNeedFormat( t ); 509 } 510 return false; 511 } 512 513 public static boolean isNotNeedFormat( TSourceToken t ) 514 { 515 if ( t == null ) 516 { 517 return false; 518 } 519 TSourceTokenList bts = t.getTokensBefore( ); 520 if ( bts.size( ) > 0 ) 521 { 522 for ( int i = 0; i < bts.size( ); i++ ) 523 { 524 if ( SourceTokenOperator.createNoFormatFlagToken( ) 525 .equals( bts.get( i ) ) ) 526 { 527 return true; 528 } 529 } 530 } 531 return false; 532 } 533 534 public static void processBlockStmt( GFmtOpt opt, TMssqlBlock stmt, 535 TSourceToken ifToken ) 536 { 537 TSourceToken startToken = stmt.getStartToken( ); 538 TSourceToken endToken = stmt.getEndToken( ); 539 if ( startToken == null || endToken == null ) 540 { 541 return; 542 } 543 int curBeginIndent = SourceTokenOperator.curColumnNumberVT( ifToken ); 544 if ( opt.beStyleBlockLeftBEOnNewline ) 545 { 546 curBeginIndent += opt.beStyleBlockLeftBEIndentSize; 547 // process the begin token 548 SourceTokenOperator.addBefore( opt, 549 startToken, 550 SourceTokenOperator.createReturnSourceToken( ) ); 551 SourceTokenOperator.addBefore( opt, 552 startToken, 553 SourceTokenOperator.createWhitespaceSourceToken( curBeginIndent ) ); 554 } 555 // process the end token 556 int curEndIndent = SourceTokenOperator.curColumnNumberVT( ifToken ) 557 + ( opt.beStyleBlockLeftBEOnNewline ? opt.beStyleBlockLeftBEIndentSize 558 : opt.beStyleBlockRightBEIndentSize ); 559 SourceTokenOperator.addBefore( opt, 560 endToken, 561 SourceTokenOperator.createReturnSourceToken( ) ); 562 SourceTokenOperator.addBefore( opt, 563 endToken, 564 SourceTokenOperator.createWhitespaceSourceToken( curEndIndent ) ); 565 566 TStatementList list = stmt.getBodyStatements( ); 567 568 // first, process the indent for the first statement 569 if ( list != null && list.size( ) > 0 ) 570 { 571 int curBlockIndent = curEndIndent + opt.beStyleBlockIndentSize; 572 TCustomSqlStatement bstmt = list.get( 0 ); 573 TSourceToken bstartToken = bstmt.getStartToken( ); 574 if ( bstartToken != null ) 575 { 576 SourceTokenOperator.addBefore( opt, 577 bstartToken, 578 SourceTokenOperator.createReturnSourceToken( ) ); 579 SourceTokenOperator.addBefore( opt, 580 bstartToken, 581 SourceTokenOperator.createWhitespaceSourceToken( curBlockIndent ) ); 582 } 583 } 584 // second, process all the empty lines between the statements 585 AllStmtsFormatter.processEmptyLine( list, opt, true ); 586 587 // third, format the statements in the begin-end block 588 if ( list != null && list.size( ) > 0 ) 589 { 590 // int curBlockIndent = curEndIndent + opt.beStyleBlockIndentSize; 591 for ( int i = 0; i < list.size( ); i++ ) 592 { 593 TCustomSqlStatement bstmt = list.get( i ); 594 // TSourceToken bstartToken = bstmt.getStartToken(); 595 // if (bstartToken != null) { 596 // SourceTokenOperator.addBefore(opt, bstartToken, 597 // SourceTokenOperator.createReturnSourceToken()); 598 // if (i != 0 && opt.insertBlankLineInBatchSqls) { 599 // TCustomSqlStatement preBstmt = list.get(i - 1); 600 // TSourceToken preBEndToken = preBstmt.getEndToken(); 601 // if (preBEndToken != null) { 602 // SourceTokenOperator.addAfter(opt, preBstmt.getEndToken(), 603 // SourceTokenOperator.createReturnSourceToken()); 604 // } 605 // } 606 // SourceTokenOperator.addBefore(opt, bstartToken, 607 // SourceTokenOperator.createWhitespaceSourceToken(curBlockIndent)); 608 // 609 // } 610 FormatterFactory.processStatement( opt, bstmt ); 611 612 } 613 } 614 615 } 616 617 public static String pp( TGSqlParser parser, GFmtOpt option ) 618 { 619 if (option.removeComment) { 620 parser = SqlFormatter.preHandleRemoveComment(parser); 621 } 622 OutputStream o = new ByteArrayOutputStream( ); 623 IPrinter printer = PrinterFactory.createTextPrinter( o ); 624 625 FormatterFactory.createAllStmtsFormatter( option ) 626 .beforeFormat( parser.sqlstatements ); 627 628 for ( int i = 0; i < parser.sqlstatements.size( ); i++ ) 629 { 630 TCustomSqlStatement sql = parser.sqlstatements.get( i ); 631 processStatement( option, sql ); 632 } 633 if ( parser.sqlstatements != null && parser.sqlstatements.size( ) > 0 ) 634 { 635 FormatterFactory.createAllStmtsFormatter( option ) 636 .doFormat( parser.sqlstatements ); 637 FormatterFactory.createAllStmtsFormatter( option ) 638 .afterFormat( parser.sqlstatements ); 639 640 if ( outputConfig == null ) 641 { 642 outputConfig = OutputConfigFactory.getOutputConfig( option, 643 parser.getDbVendor( ) ); 644 } 645 646 printer.setOutputConfig( outputConfig ); 647 printer.print( parser.sqlstatements.get( 0 ).getStartToken( ).container ); 648 } 649 650 clearAllObject( option.sessionId ); 651 return o.toString( ); 652 653 } 654 655 /** 656 * Fault-tolerant formatter entry point (pp2). Unlike {@link #pp(TGSqlParser, GFmtOpt)}, 657 * this does <b>not</b> require {@code parser.parse()} to have returned 0: it 658 * re-tokenizes {@code parser.sqltext} internally, splits the script into 659 * statement regions, formats each region independently, and recovers 660 * gracefully from malformed input. It never throws for non-null inputs and 661 * preserves every solid input token. 662 * 663 * <p>This is the single additive pp2 bridge (plan ยง4.1/S17). It does not 664 * change the behavior of {@link #pp(TGSqlParser, GFmtOpt)} or any other 665 * existing method. The heavy lifting lives in 666 * {@code gudusoft.gsqlparser.pp2.engine.Pp2Engine}. 667 * 668 * @param parser carries the SQL text ({@code parser.sqltext}) and dialect 669 * ({@code parser.getDbVendor()}); need not be parsed first 670 * @param opts pp2 formatting options; must not be null 671 * @return a structured {@link Pp2FormatResult} with per-region renderer 672 * choice, status, and diagnostics; never null 673 * @throws NullPointerException if {@code parser} or {@code opts} is null 674 */ 675 public static Pp2FormatResult pp2( TGSqlParser parser, Pp2FormatOptions opts ) 676 { 677 if ( parser == null ) throw new NullPointerException( "parser" ); 678 if ( opts == null ) throw new NullPointerException( "opts" ); 679 String sql = parser.sqltext == null ? "" : parser.sqltext; 680 return new Pp2Engine( ).format( sql, parser.getDbVendor( ), opts ); 681 } 682 683 /** 684 * Convenience overload mirroring the {@link #pp(TGSqlParser, GFmtOpt)} 685 * signature: returns the formatted text directly. The caller's 686 * {@link GFmtOpt} is copied into a {@link Pp2FormatOptions} via 687 * {@link Pp2FormatOptions#from(GFmtOpt)} so casing/comma/indent options 688 * carry over (giving byte-parity with {@code pp()} on parseable input). 689 * 690 * @param parser carries the SQL text and dialect; need not be parsed first 691 * @param opt existing formatter options; must not be null 692 * @return the formatted SQL text; never null 693 * @throws NullPointerException if {@code parser} or {@code opt} is null 694 */ 695 public static String pp2( TGSqlParser parser, GFmtOpt opt ) 696 { 697 if ( parser == null ) throw new NullPointerException( "parser" ); 698 if ( opt == null ) throw new NullPointerException( "opt" ); 699 return pp2( parser, Pp2FormatOptions.from( opt ) ).getText( ); 700 } 701 702 public static OutputConfig getOutputConfig( ) 703 { 704 return outputConfig; 705 } 706 707 public static void setOutputConfig( OutputConfig outputConfig ) 708 { 709 FormatterFactory.outputConfig = outputConfig; 710 } 711 712 public static AllStmtsFormatter createAllStmtsFormatter( GFmtOpt option ) 713 { 714 return AllStmtsFormatterBuilder.create( option ); 715 } 716 717 public static void clearAllObject( String sessionId ) 718 { 719 FormatterFactory.clear( sessionId ); 720 ProcessorFactory.clear( sessionId ); 721 MediatorFactory.clear( sessionId ); 722 } 723 724 public static void clear( String sessionId ) 725 { 726 synchronized ( object ) 727 { 728 List<String> removedKeys = new ArrayList<String>( ); 729 for ( String key : formatter.keySet( ) ) 730 { 731 if ( key.startsWith( sessionId ) ) 732 { 733 removedKeys.add( key ); 734 } 735 } 736 for ( String key : removedKeys ) 737 { 738 formatter.remove( key ); 739 } 740 } 741 } 742}