-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathzabap_p_sniffer.prog.abap
840 lines (693 loc) · 28.1 KB
/
zabap_p_sniffer.prog.abap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
*&---------------------------------------------------------------------*
*& Report zabap_p_sniffer
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zabap_p_sniffer.
TABLES:trdir,tadir,seoclasstx,tlibt,tfdir.
DATA _pattern TYPE text255.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE t01.
SELECT-OPTIONS s_patern FOR _pattern OBLIGATORY NO INTERVALS.
PARAMETERS p_asregx AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE t02.
SELECT-OPTIONS s_repnam FOR trdir-name.
SELECT-OPTIONS s_reptyp FOR trdir-subc.
SELECTION-SCREEN END OF BLOCK b2.
SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE t03.
SELECT-OPTIONS s_packag FOR tadir-devclass.
SELECTION-SCREEN END OF BLOCK b3.
SELECTION-SCREEN BEGIN OF BLOCK b4 WITH FRAME TITLE t04.
SELECT-OPTIONS s_funcnm FOR tfdir-funcname.
SELECT-OPTIONS s_funcgr FOR tlibt-area.
SELECTION-SCREEN END OF BLOCK b4.
SELECTION-SCREEN BEGIN OF BLOCK b5 WITH FRAME TITLE t05.
SELECT-OPTIONS s_clsnam FOR seoclasstx-clsname.
SELECT-OPTIONS s_intfac FOR seoclasstx-clsname.
SELECTION-SCREEN END OF BLOCK b5.
SELECTION-SCREEN BEGIN OF BLOCK b6 WITH FRAME TITLE t06.
SELECT-OPTIONS s_enhanc FOR trdir-name.
PARAMETERS p_withmd AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK b6.
CLASS lcl_sniffer DEFINITION.
PUBLIC SECTION.
TYPES ty_source_names TYPE STANDARD TABLE OF tadir-obj_name WITH EMPTY KEY.
TYPES ty_range_repname TYPE RANGE OF trdir-name.
TYPES ty_range_reptype TYPE RANGE OF trdir-subc.
TYPES ty_range_package TYPE RANGE OF tadir-devclass.
TYPES ty_range_funcnam TYPE RANGE OF tfdir-funcname.
TYPES ty_range_funcgrp TYPE RANGE OF tlibt-area.
TYPES ty_range_clsname TYPE RANGE OF seoclasstx-clsname.
TYPES ty_range_intface TYPE RANGE OF seoclasstx-clsname.
TYPES ty_range_enhance TYPE RANGE OF trdir-name.
TYPES: BEGIN OF ty_sniff_result,
repname TYPE trdir-name,
lineidx TYPE n LENGTH 6,
linesrc TYPE text255,
END OF ty_sniff_result.
TYPES ty_sniff_results TYPE TABLE OF ty_sniff_result WITH EMPTY KEY.
TYPES ty_pattern TYPE text255.
TYPES ty_pattern_tab TYPE TABLE OF ty_pattern WITH EMPTY KEY.
CLASS-METHODS get_instance
RETURNING VALUE(ro_instance) TYPE REF TO lcl_sniffer.
METHODS sniff
IMPORTING !pattern TYPE ty_pattern_tab
isregex TYPE abap_bool OPTIONAL
repname TYPE ty_range_repname OPTIONAL
reptype TYPE ty_range_reptype OPTIONAL
!package TYPE ty_range_package OPTIONAL
funcgrp TYPE ty_range_funcgrp OPTIONAL
funcnam TYPE ty_range_funcnam OPTIONAL
clsname TYPE ty_range_clsname OPTIONAL
intface TYPE ty_range_intface OPTIONAL
enhance TYPE ty_range_enhance OPTIONAL
withmod TYPE abap_bool OPTIONAL
!comment TYPE abap_bool OPTIONAL
RETURNING VALUE(rt_result) TYPE ty_sniff_results.
PRIVATE SECTION.
METHODS get_source_names
IMPORTING repname TYPE ty_range_repname
reptype TYPE ty_range_reptype
!package TYPE ty_range_package
funcgrp TYPE ty_range_funcgrp
funcnam TYPE ty_range_funcnam
clsname TYPE ty_range_clsname
intface TYPE ty_range_intface
enhance TYPE ty_range_enhance
withmod TYPE abap_bool
RETURNING VALUE(rt_source_names) TYPE ty_source_names.
METHODS search_sources
IMPORTING !pattern TYPE clike
isregex TYPE abap_bool
sources TYPE ty_source_names
!comment TYPE abap_bool
RETURNING VALUE(rt_result) TYPE ty_sniff_results.
METHODS add_to_hit_list
IMPORTING repname TYPE trdir-name
repsource TYPE abaptxt255_tab
matchres TYPE match_result
!comment TYPE abap_bool
CHANGING ct_result TYPE ty_sniff_results.
METHODS get_program_names
IMPORTING repname TYPE ty_range_repname
reptype TYPE ty_range_reptype
RETURNING VALUE(rt_source_names) TYPE ty_source_names.
METHODS get_report_names
IMPORTING !package TYPE ty_range_package
RETURNING VALUE(rt_source_names) TYPE ty_source_names.
METHODS get_function_names
IMPORTING funcnam TYPE ty_range_funcnam
!package TYPE ty_range_package
RETURNING VALUE(rt_source_names) TYPE ty_source_names.
METHODS get_function_group_names
IMPORTING funcgrp TYPE ty_range_funcgrp
!package TYPE ty_range_package
RETURNING VALUE(rt_source_names) TYPE ty_source_names.
METHODS get_class_names
IMPORTING clsname TYPE ty_range_clsname
!package TYPE ty_range_package
RETURNING VALUE(rt_source_names) TYPE ty_source_names.
METHODS get_interface_names
IMPORTING intface TYPE ty_range_intface
!package TYPE ty_range_package
RETURNING VALUE(rt_source_names) TYPE ty_source_names.
METHODS get_enhancement_names
IMPORTING enhance TYPE ty_range_enhance
!package TYPE ty_range_package
RETURNING VALUE(rt_source_names) TYPE ty_source_names.
METHODS get_modification_names
IMPORTING withmod TYPE abap_bool
RETURNING VALUE(rt_source_names) TYPE ty_source_names.
METHODS get_class_includes
IMPORTING clsname TYPE seoclsname
RETURNING VALUE(rt_includes) TYPE seoincl_t.
METHODS get_method_include
IMPORTING clsname TYPE seoclsname
cpdname TYPE seocpdname
RETURNING VALUE(rv_include) TYPE progname.
METHODS get_function_include
IMPORTING funcname TYPE funcname
RETURNING VALUE(rv_include) TYPE progname.
METHODS get_funcgroup_program
IMPORTING funcgroup TYPE tlibt-area
RETURNING VALUE(rv_program) TYPE progname.
METHODS get_includes
CHANGING ct_source_names TYPE ty_source_names.
METHODS show_progress_bar
IMPORTING percent TYPE i
content TYPE clike.
CLASS-DATA instance TYPE REF TO lcl_sniffer.
ENDCLASS.
CLASS lcl_sniffer IMPLEMENTATION.
METHOD get_instance.
IF instance IS NOT BOUND.
instance = NEW #( ).
ENDIF.
ro_instance = instance.
ENDMETHOD.
METHOD sniff.
DATA lt_source_names TYPE ty_source_names.
DATA lv_pattern TYPE ty_pattern.
lt_source_names = get_source_names( repname = repname
reptype = reptype
package = package
funcgrp = funcgrp
funcnam = funcnam
clsname = clsname
intface = intface
enhance = enhance
withmod = withmod ).
LOOP AT pattern INTO lv_pattern.
APPEND LINES OF search_sources( pattern = lv_pattern
isregex = isregex
sources = lt_source_names
comment = comment ) TO rt_result.
ENDLOOP.
ENDMETHOD.
METHOD get_source_names.
APPEND LINES OF me->get_program_names( repname = repname
reptype = reptype )
TO rt_source_names.
APPEND LINES OF me->get_report_names( package = package )
TO rt_source_names.
APPEND LINES OF me->get_class_names( clsname = clsname
package = package )
TO rt_source_names.
APPEND LINES OF me->get_interface_names( intface = intface
package = package )
TO rt_source_names.
APPEND LINES OF me->get_function_names( funcnam = funcnam
package = package )
TO rt_source_names.
APPEND LINES OF me->get_function_group_names( funcgrp = funcgrp
package = package )
TO rt_source_names.
APPEND LINES OF me->get_enhancement_names( enhance = enhance
package = package )
TO rt_source_names.
APPEND LINES OF me->get_modification_names( withmod = withmod )
TO rt_source_names.
IF rt_source_names IS INITIAL.
RETURN.
ENDIF.
get_includes( CHANGING ct_source_names = rt_source_names ).
SORT rt_source_names STABLE BY table_line ASCENDING.
DELETE ADJACENT DUPLICATES FROM rt_source_names COMPARING table_line.
ENDMETHOD.
METHOD show_progress_bar.
CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
EXPORTING
percentage = percent
text = content.
ENDMETHOD.
METHOD get_includes.
DATA lt_includes TYPE ty_source_names.
DATA lt_new_sources TYPE ty_source_names.
DATA class_name TYPE seoclsname.
DATA lv_percent TYPE i.
DATA lv_old_percent TYPE i.
DATA lv_source_name LIKE LINE OF ct_source_names.
DATA lv_source_size TYPE i.
lv_source_size = lines( ct_source_names ).
LOOP AT ct_source_names INTO lv_source_name.
IF sy-batch IS INITIAL.
lv_percent = ( sy-tabix * 100 ) / lv_source_size.
IF lv_percent <> lv_old_percent.
show_progress_bar( percent = lv_percent
content = |Includes finding { sy-tabix }/{ lv_source_size }| ).
lv_old_percent = lv_percent.
ENDIF.
ENDIF.
CLEAR lt_includes.
CASE lv_source_name+30(2).
WHEN 'CP'. " class pool
DELETE ct_source_names INDEX sy-tabix.
class_name = lv_source_name(30).
TRANSLATE class_name USING '= '.
APPEND LINES OF me->get_class_includes( clsname = class_name )
TO lt_new_sources.
WHEN 'IP'. " interface pool
DELETE ct_source_names INDEX sy-tabix.
lv_source_name+30(1) = 'U'.
APPEND lv_source_name TO lt_new_sources.
ENDCASE.
CALL FUNCTION 'RS_GET_ALL_INCLUDES'
EXPORTING
program = lv_source_name
TABLES
includetab = lt_includes
EXCEPTIONS
OTHERS = 0.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
DELETE lt_includes WHERE table_line CP 'LSVIM*'.
APPEND LINES OF lt_includes TO lt_new_sources.
ENDLOOP.
APPEND LINES OF lt_new_sources TO ct_source_names.
ENDMETHOD.
METHOD search_sources.
DATA lv_source_name LIKE LINE OF sources.
DATA lt_source TYPE abaptxt255_tab.
DATA lt_result TYPE match_result_tab.
DATA ls_result LIKE LINE OF lt_result.
DATA lv_source_size TYPE i.
DATA lv_progbar_text TYPE string.
DATA lv_progbar_percent TYPE i.
DATA lv_progbar_old_percent TYPE i.
lv_source_size = lines( sources ).
LOOP AT sources INTO lv_source_name.
READ REPORT lv_source_name INTO lt_source.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
IF sy-batch IS INITIAL.
lv_progbar_percent = ( sy-tabix * 100 ) / lv_source_size.
lv_progbar_text = |Sniffing... for: '{ pattern }' { sy-tabix }/{ lv_source_size } | &&
|hits:{ lines( rt_result ) }|.
IF lv_progbar_percent <> lv_progbar_old_percent.
show_progress_bar( percent = lv_progbar_percent
content = lv_progbar_text ).
lv_progbar_old_percent = lv_progbar_percent.
ENDIF.
ENDIF.
IF isregex = abap_true.
FIND ALL OCCURRENCES OF REGEX pattern
IN TABLE lt_source
IN CHARACTER MODE
IGNORING CASE
RESULTS lt_result.
ELSE.
FIND ALL OCCURRENCES OF pattern
IN TABLE lt_source
IN CHARACTER MODE
IGNORING CASE
RESULTS lt_result.
ENDIF.
IF lt_result IS INITIAL.
CONTINUE.
ENDIF.
LOOP AT lt_result INTO ls_result.
add_to_hit_list( EXPORTING repname = lv_source_name
repsource = lt_source
matchres = ls_result
comment = comment
CHANGING ct_result = rt_result ).
ENDLOOP.
CLEAR lt_source.
CLEAR lt_result.
ENDLOOP.
ENDMETHOD.
METHOD add_to_hit_list.
DATA source_line LIKE LINE OF repsource.
READ TABLE repsource INDEX matchres-line INTO source_line.
IF sy-subrc <> 0.
RETURN.
ENDIF.
" if all line is comment ignore this match
IF source_line-line(1) CA '"*' AND comment = abap_true.
RETURN.
ENDIF.
APPEND VALUE #( repname = repname
linesrc = source_line-line
lineidx = matchres-line )
TO ct_result.
ENDMETHOD.
METHOD get_program_names.
CHECK repname IS NOT INITIAL
OR reptype IS NOT INITIAL.
SELECT name FROM trdir
WHERE name IN @repname
AND subc IN @reptype
INTO TABLE @rt_source_names.
ENDMETHOD.
METHOD get_report_names.
CHECK package IS NOT INITIAL.
SELECT obj_name FROM tadir
WHERE pgmid = 'R3TR'
AND object = 'PROG'
AND devclass IN @package
AND delflag = @space
INTO TABLE @rt_source_names.
ENDMETHOD.
METHOD get_function_names.
DATA lt_function_names TYPE TABLE OF tfdir-funcname.
DATA lv_function_name LIKE LINE OF lt_function_names.
CHECK package IS NOT INITIAL
OR funcnam IS NOT INITIAL.
SELECT tfdir~funcname
FROM tfdir
INNER JOIN
enlfdir ON enlfdir~funcname = tfdir~funcname
INNER JOIN
tadir ON tadir~obj_name = enlfdir~area
WHERE tadir~pgmid = 'R3TR'
AND tadir~object = 'FUGR'
AND tadir~devclass IN @package
AND tadir~delflag = @space
AND tfdir~funcname IN @funcnam
AND enlfdir~active = @abap_true
INTO TABLE @lt_function_names.
LOOP AT lt_function_names INTO lv_function_name.
APPEND me->get_function_include( funcname = lv_function_name )
TO rt_source_names.
ENDLOOP.
ENDMETHOD.
METHOD get_function_group_names.
DATA lt_obj_names TYPE TABLE OF tadir-obj_name.
DATA lv_obj_name LIKE LINE OF lt_obj_names.
CHECK package IS NOT INITIAL
OR funcgrp IS NOT INITIAL.
SELECT DISTINCT tadir~obj_name FROM tadir
WHERE tadir~pgmid = 'R3TR'
AND tadir~object = 'FUGR'
AND tadir~devclass IN @package
AND tadir~delflag = @space
AND tadir~obj_name IN @funcgrp
INTO TABLE @lt_obj_names.
LOOP AT lt_obj_names INTO lv_obj_name.
APPEND me->get_funcgroup_program( funcgroup = CONV #( lv_obj_name ) )
TO rt_source_names.
ENDLOOP.
ENDMETHOD.
METHOD get_class_names.
DATA lt_obj_names TYPE TABLE OF tadir-obj_name.
DATA lv_obj_name LIKE LINE OF lt_obj_names.
CHECK clsname IS NOT INITIAL
OR package IS NOT INITIAL.
SELECT obj_name FROM tadir
WHERE pgmid = 'R3TR'
AND object = 'CLAS'
AND devclass IN @package
AND obj_name IN @clsname
AND delflag = @space
INTO TABLE @lt_obj_names.
LOOP AT lt_obj_names INTO lv_obj_name.
APPEND cl_oo_classname_service=>get_classpool_name( |{ lv_obj_name }| )
TO rt_source_names.
ENDLOOP.
ENDMETHOD.
METHOD get_interface_names.
DATA lt_obj_names TYPE TABLE OF tadir-obj_name.
DATA lv_obj_name LIKE LINE OF lt_obj_names.
CHECK intface IS NOT INITIAL
OR package IS NOT INITIAL.
SELECT obj_name FROM tadir
WHERE pgmid = 'R3TR'
AND object = 'INTF'
AND devclass IN @package
AND obj_name IN @intface
AND delflag = @space
INTO TABLE @lt_obj_names.
LOOP AT lt_obj_names INTO lv_obj_name.
APPEND cl_oo_classname_service=>get_interfacepool_name( |{ lv_obj_name }| )
TO rt_source_names.
ENDLOOP.
ENDMETHOD.
METHOD get_enhancement_names.
DATA lt_obj_names TYPE TABLE OF tadir-obj_name.
DATA lv_obj_name LIKE LINE OF lt_obj_names.
CHECK package IS NOT INITIAL
OR enhance IS NOT INITIAL.
SELECT obj_name FROM tadir
WHERE pgmid = 'R3TR'
AND object = 'ENHO'
AND delflag = @space
AND devclass IN @package
AND obj_name IN @enhance
AND delflag = @space
INTO TABLE @lt_obj_names.
LOOP AT lt_obj_names INTO lv_obj_name.
TRANSLATE lv_obj_name(30) USING ' ='.
lv_obj_name+30 = 'E'.
APPEND lv_obj_name TO rt_source_names.
ENDLOOP.
ENDMETHOD.
METHOD get_modification_names.
DATA lt_smodilog TYPE TABLE OF smodilog.
DATA ls_modi LIKE LINE OF lt_smodilog.
CHECK withmod = abap_true.
DATA lv_obj_name TYPE tadir-obj_name.
SELECT * FROM smodilog
WHERE operation NOT IN ( 'MIGR', 'IMPL', 'TRSL', 'NOTE' )
AND inactive = @space
AND int_type NOT IN ('DUMY')
AND obj_type IN ( 'PROG', 'LDBA', 'FUGR', 'FUGX', 'FUGS', 'CLAS' )
AND sub_type IN ( 'REPS', 'METH', 'FUNC', 'LDBA', 'CLAS', 'CINC', 'FUG', 'PROG' )
ORDER BY PRIMARY KEY
INTO TABLE @lt_smodilog.
LOOP AT lt_smodilog INTO ls_modi.
CASE ls_modi-sub_type.
WHEN 'REPS'. " report
APPEND ls_modi-sub_name TO rt_source_names.
WHEN 'METH'. " method
APPEND me->get_method_include( clsname = CONV #( ls_modi-obj_name )
cpdname = CONV #( ls_modi-sub_name+30 ) )
TO rt_source_names.
WHEN 'FUNC'. " function
APPEND me->get_function_include( funcname = CONV #( ls_modi-sub_name ) )
TO rt_source_names.
WHEN 'LDBA'. " logical database
APPEND |{ ls_modi-sub_name }SEL| TO rt_source_names.
APPEND |SAP{ ls_modi-sub_name }| TO rt_source_names.
WHEN 'CLAS'. " class
APPEND LINES OF me->get_class_includes( clsname = CONV #( ls_modi-obj_name ) )
TO rt_source_names.
WHEN 'CINC'. " class include
lv_obj_name = ls_modi-sub_name.
TRANSLATE lv_obj_name USING ' ='.
lv_obj_name+30 = SWITCH #( ls_modi-sub_type
WHEN 'CPUB' THEN 'CU'
WHEN 'CPRO' THEN 'CO'
WHEN 'CPRI' THEN 'CI' ).
APPEND lv_obj_name TO rt_source_names.
WHEN 'FUGR'. " function group
APPEND me->get_funcgroup_program( funcgroup = CONV #( lv_obj_name ) )
TO rt_source_names.
WHEN 'PROG'. " program
APPEND lv_obj_name TO rt_source_names.
ENDCASE.
ENDLOOP.
ENDMETHOD.
METHOD get_class_includes.
cl_oo_classname_service=>get_all_class_includes( EXPORTING class_name = clsname
RECEIVING result = rt_includes
EXCEPTIONS OTHERS = 1 ).
DELETE rt_includes WHERE table_line+30(2) = 'CS'
OR table_line+30(2) = 'CP'.
ENDMETHOD.
METHOD get_method_include.
cl_oo_classname_service=>get_method_include( EXPORTING mtdkey = VALUE #( clsname = clsname
cpdname = cpdname )
RECEIVING result = rv_include
EXCEPTIONS OTHERS = 1 ).
ENDMETHOD.
METHOD get_function_include.
CALL FUNCTION 'FUNCTION_EXISTS'
EXPORTING
funcname = funcname
IMPORTING
include = rv_include
EXCEPTIONS
OTHERS = 1.
ENDMETHOD.
METHOD get_funcgroup_program.
DATA lv_funcgroup TYPE rs38l-area.
lv_funcgroup = funcgroup.
CALL FUNCTION 'FUNCTION_INCLUDE_CONCATENATE'
CHANGING
program = rv_program
complete_area = lv_funcgroup
EXCEPTIONS
OTHERS = 1.
ENDMETHOD.
ENDCLASS.
CLASS lcl_application DEFINITION.
PUBLIC SECTION.
METHODS initialization.
METHODS start_of_selection.
METHODS end_of_selection.
METHODS handle_on_f4_for_field
IMPORTING !field TYPE clike
CHANGING cv_value TYPE any.
PRIVATE SECTION.
TYPES: BEGIN OF ty_result_header,
repname TYPE trdir-name,
expand TYPE abap_bool,
END OF ty_result_header.
METHODS on_link_click
FOR EVENT link_click OF cl_salv_events_hierseq
IMPORTING sender
!level
!row
!column.
METHODS build_alv
RAISING cx_salv_data_error
cx_salv_not_found.
DATA mo_sniffer TYPE REF TO lcl_sniffer.
DATA mt_results_body TYPE lcl_sniffer=>ty_sniff_results.
DATA ms_results_body LIKE LINE OF mt_results_body.
DATA mt_results_header TYPE TABLE OF ty_result_header.
DATA ms_results_header LIKE LINE OF mt_results_header.
ENDCLASS.
CLASS lcl_application IMPLEMENTATION.
METHOD initialization.
mo_sniffer = lcl_sniffer=>get_instance( ).
sy-title = 'ABAP Sniffer( Code Scanner )'.
t01 = 'Search Term'.
%_s_patern_%_app_%-text = 'Search for'.
%_p_asregx_%_app_%-text = 'Search is regex'.
t02 = 'Program Selection'.
%_s_repnam_%_app_%-text = 'Program name'.
%_s_reptyp_%_app_%-text = 'Program type'.
t03 = 'Package Selection'.
%_s_packag_%_app_%-text = 'Package'.
t04 = 'Function / Function Group Selection'.
%_s_funcgr_%_app_%-text = 'Function group'.
%_s_funcnm_%_app_%-text = 'Function name'.
t05 = 'Class / Interface Selection'.
%_s_clsnam_%_app_%-text = 'Class'.
%_s_intfac_%_app_%-text = 'Interface'.
t06 = 'Enhancement Selection'.
%_s_enhanc_%_app_%-text = 'Enhancement'.
%_p_withmd_%_app_%-text = 'With modifications'.
DATA ls_restrict TYPE sscr_restrict.
ls_restrict = VALUE #( opt_list_tab = VALUE #( ( name = 'RESTRICT'
options = VALUE #( cp = abap_true
eq = abap_true ) ) )
ass_tab = VALUE #( ( kind = 'S'
name = 'S_PATERN'
sg_main = 'I'
op_main = 'RESTRICT'
op_addy = 'RESTRICT' ) ) ).
CALL FUNCTION 'SELECT_OPTIONS_RESTRICT'
EXPORTING
program = sy-repid
restriction = ls_restrict
EXCEPTIONS
OTHERS = 1.
ENDMETHOD.
METHOD start_of_selection.
DATA lt_pattern TYPE lcl_sniffer=>ty_pattern_tab.
LOOP AT s_patern INTO s_patern.
APPEND s_patern-low TO lt_pattern.
ENDLOOP.
TRY.
mt_results_body = mo_sniffer->sniff( pattern = lt_pattern
isregex = p_asregx
repname = s_repnam[]
reptype = s_reptyp[]
package = s_packag[]
funcgrp = s_funcgr[]
funcnam = s_funcnm[]
clsname = s_clsnam[]
intface = s_intfac[]
enhance = s_enhanc[]
withmod = p_withmd ).
CATCH cx_root INTO DATA(lx_root).
MESSAGE lx_root->get_text( ) TYPE 'E'.
ENDTRY.
ENDMETHOD.
METHOD end_of_selection.
IF mt_results_body IS INITIAL.
MESSAGE |Searched but not found!.| TYPE 'S'.
RETURN.
ENDIF.
LOOP AT mt_results_body INTO DATA(table) GROUP BY ( repname = table-repname ) INTO DATA(group).
APPEND group-repname TO mt_results_header.
ENDLOOP.
TRY.
build_alv( ).
CATCH cx_root INTO DATA(lx_root).
MESSAGE lx_root->get_text( ) TYPE 'E'.
ENDTRY.
ENDMETHOD.
METHOD on_link_click.
CASE level.
WHEN 1.
WHEN 2.
READ TABLE mt_results_body INDEX row INTO ms_results_body.
IF sy-subrc <> 0.
RETURN.
ENDIF.
CALL FUNCTION 'EDITOR_PROGRAM'
EXPORTING
appid = 'PG'
display = abap_true
program = ms_results_body-repname
line = ms_results_body-lineidx
topline = ms_results_body-lineidx
EXCEPTIONS
OTHERS = 0.
ENDCASE.
ENDMETHOD.
METHOD build_alv.
DATA lo_salv TYPE REF TO cl_salv_hierseq_table.
DATA lo_column TYPE REF TO cl_salv_column_hierseq.
DATA lo_disp_settings TYPE REF TO cl_salv_display_settings.
cl_salv_hierseq_table=>factory(
EXPORTING t_binding_level1_level2 = VALUE #( ( master = 'REPNAME' slave = 'REPNAME' ) )
IMPORTING r_hierseq = lo_salv
CHANGING t_table_level1 = mt_results_header
t_table_level2 = mt_results_body ).
SET HANDLER on_link_click FOR lo_salv->get_event( ).
lo_salv->get_layout( )->set_key( VALUE #( report = sy-repid
handle = 'XXXX' ) ).
lo_salv->get_layout( )->set_save_restriction( ).
lo_salv->get_functions( )->set_all( ).
lo_disp_settings = lo_salv->get_display_settings( ).
lo_disp_settings->set_list_header( value = |{ lines( mt_results_body ) } Hits Found!| ).
lo_salv->get_columns( level = 1 )->set_expand_column( value = 'EXPAND' ).
lo_salv->get_level( level = 1 )->set_items_expanded( ).
LOOP AT lo_salv->get_columns( level = 1 )->get( ) REFERENCE INTO DATA(lr_column).
CASE lr_column->columnname.
WHEN 'EXPAND'.
lr_column->r_column->set_technical( ).
ENDCASE.
ENDLOOP.
LOOP AT lo_salv->get_columns( level = 2 )->get( ) REFERENCE INTO lr_column.
lo_column ?= lr_column->r_column.
CASE lr_column->columnname.
WHEN 'REPNAME'.
lo_column->set_technical( ).
WHEN 'LINESRC'.
lo_column->set_cell_type( if_salv_c_cell_type=>hotspot ).
lo_column->set_long_text( value = 'Source' ).
WHEN 'LINEIDX'.
lo_column->set_long_text( value = 'Line' ).
lo_column->set_color( value = VALUE #( col = '4' ) ).
lo_column->set_cell_type( if_salv_c_cell_type=>hotspot ).
lo_column->set_leading_zero( ).
ENDCASE.
ENDLOOP.
lo_salv->display( ).
ENDMETHOD.
METHOD handle_on_f4_for_field.
CASE field.
WHEN 'REPNAM'.
CALL FUNCTION 'REPOSITORY_INFO_SYSTEM_F4'
EXPORTING
object_type = 'PROG'
object_name = cv_value
suppress_selection = 'X'
IMPORTING
object_name_selected = cv_value
EXCEPTIONS
cancel = 0.
ENDCASE.
ENDMETHOD.
ENDCLASS.
LOAD-OF-PROGRAM.
DATA(app) = NEW lcl_application( ).
INITIALIZATION.
app->initialization( ).
AT SELECTION-SCREEN ON VALUE-REQUEST FOR s_repnam-low.
app->handle_on_f4_for_field( EXPORTING field = 'REPNAM'
CHANGING cv_value = s_repnam-low ).
AT SELECTION-SCREEN ON VALUE-REQUEST FOR s_repnam-high.
app->handle_on_f4_for_field( EXPORTING field = 'REPNAM'
CHANGING cv_value = s_repnam-high ).
START-OF-SELECTION.
app->start_of_selection( ).
END-OF-SELECTION.
app->end_of_selection( ).