1111import java .util .Optional ;
1212import java .util .Set ;
1313import java .util .UUID ;
14+ import java .util .stream .Collectors ;
1415
1516import org .apache .commons .lang3 .StringUtils ;
1617import org .eclipse .core .resources .IFile ;
99100import com .google .common .base .Strings ;
100101import com .google .common .eventbus .EventBus ;
101102import com .google .common .eventbus .Subscribe ;
103+ import java .util .Timer ;
104+ import java .util .TimerTask ;
102105
103106public class CheckmarxView extends ViewPart implements EventHandler {
104107
@@ -113,6 +116,11 @@ public class CheckmarxView extends ViewPart implements EventHandler {
113116 private static final String FORMATTED_SCAN_LABEL = "%s %s" ;
114117 private static final String FORMATTED_SCAN_LABEL_LATEST = "%s %s (%s)" ;
115118
119+ private Timer debounceTimer = new Timer ("ProjectSearchDebounce" , true );
120+ private TimerTask pendingSearchTask ;
121+ private static final int DEBOUNCE_DELAY_MS = 400 ;
122+ private volatile String latestProjectSearchTerm = "" ;
123+
116124 private static final int SCROLL_WIDTH = 30 ;
117125 /**
118126 * The ID of the view as specified by the extension.
@@ -815,21 +823,61 @@ protected IStatus run(IProgressMonitor arg0) {
815823 });
816824
817825 // Add ModifyListener to handle manual text input for projects
818- projectComboViewer .getCombo ().addModifyListener (e -> {
819- String enteredProject = projectComboViewer .getCombo ().getText ();
820-
821- // Check if text was modified and project doesn't exist
822- boolean projectExists = currentProjects .stream ()
823- .anyMatch (p -> p .getName ().equals (enteredProject ));
824-
825- if (!projectExists ) {
826- updateStartScanButton (false ); // Disable scan button
827- } else {
828- // Only enable if we also have a valid branch
829- boolean validBranch = !currentBranch .isEmpty () && currentBranches .contains (currentBranch );
830- updateStartScanButton (validBranch );
826+ projectComboViewer .getCombo ().addModifyListener (e -> {
827+ String enteredProject = projectComboViewer .getCombo ().getText ().trim ();
828+ // Skip search if the text is the default instruction
829+ if (enteredProject .equals (PROJECT_COMBO_VIEWER_TEXT )) {
830+ updateStartScanButton (false ); // Disable scan button
831+ return ;
832+ }
833+
834+ latestProjectSearchTerm = enteredProject ; // Track the latest term
835+ List <String > matchedProjects ;
836+ matchedProjects = currentProjects .stream ().map (Project ::getName )
837+ .filter (name -> name != null && name .toLowerCase ().contains (enteredProject .toLowerCase ())).limit (100 )
838+ .collect (Collectors .toList ());
839+
840+ if (matchedProjects .isEmpty ()) {
841+ CxLogger .info ("Entered project is not exist in current projects list" );
842+ // Cancel any pending search
843+ if (pendingSearchTask != null ) {
844+ pendingSearchTask .cancel ();
845+ }
846+ // Schedule a new search after the debounce delay
847+ pendingSearchTask = new java .util .TimerTask () {
848+ @ Override
849+ public void run () {
850+ final String searchTerm = latestProjectSearchTerm ; // Capture the term for this search
851+ // Schedule a background job for the server search
852+ Job job = new Job ("Checkmarx: Searching for project on server..." ) {
853+ @ Override
854+ protected IStatus run (IProgressMonitor monitor ) {
855+ List <Project > searchedProjects ;
856+ try {
857+ searchedProjects = DataProvider .getInstance ().getProjects (searchTerm );
858+ Display .getDefault ().asyncExec (() -> {
859+ if (searchTerm .equals (latestProjectSearchTerm )) {
860+ // Update UI in UI thread
861+ if (searchedProjects != null && !searchedProjects .isEmpty ()) {
862+ projectComboViewer .setInput (searchedProjects );
863+ currentProjects = searchedProjects ;
864+ } else {
865+ updateStartScanButton (false ); // Disable scan button
866+ }
867+ }
868+ });
869+ } catch (Exception ex ) {
870+ ex .printStackTrace ();
871+ }
872+ return Status .OK_STATUS ;
873+ }
874+ };
875+ job .schedule ();
831876 }
832- });
877+ };
878+ debounceTimer .schedule (pendingSearchTask , DEBOUNCE_DELAY_MS );
879+ }
880+ });
833881 }
834882 /**
835883 * Update state variables and make plugin fields loading when project changes
@@ -1818,20 +1866,20 @@ private void layoutAttackVectorItemComposite() {
18181866 }
18191867
18201868 private void drawPackageData (DisplayModel selectedItem ) {
1821- ScrolledComposite sc = new ScrolledComposite (attackVectorCompositePanel , SWT .H_SCROLL | SWT .V_SCROLL );
1869+ ScrolledComposite sc = new ScrolledComposite (attackVectorCompositePanel , SWT .H_SCROLL | SWT .V_SCROLL );
18221870
1823- Composite child = new Composite (sc , SWT .NONE );
1824- child .setLayoutData (new GridData (GridData .FILL , GridData .BEGINNING , true , true ));
1825- child .setLayout (new GridLayout (1 , false ));
1826- child .setBackground (attackVectorCompositePanel .getBackground ());
1871+ Composite child = new Composite (sc , SWT .NONE );
1872+ child .setLayoutData (new GridData (GridData .FILL , GridData .BEGINNING , true , true ));
1873+ child .setLayout (new GridLayout (1 , false ));
1874+ child .setBackground (attackVectorCompositePanel .getBackground ());
18271875
1828- drawAttackVectorTitle (child , PluginConstants .PACKAGE_DATA );
1829- drawIndividualPackageData (child , selectedItem .getResult ().getData ().getPackageData ());
1876+ drawAttackVectorTitle (child , PluginConstants .PACKAGE_DATA );
1877+ drawIndividualPackageData (child , selectedItem .getResult ().getData ().getPackageData ());
18301878
1831- sc .setContent (child );
1832- sc .setMinSize (child .computeSize (SWT .DEFAULT , SWT .DEFAULT ));
1833- sc .setExpandHorizontal (true );
1834- sc .setExpandVertical (true );
1879+ sc .setContent (child );
1880+ sc .setMinSize (child .computeSize (SWT .DEFAULT , SWT .DEFAULT ));
1881+ sc .setExpandHorizontal (true );
1882+ sc .setExpandVertical (true );
18351883 }
18361884
18371885 /**
@@ -1942,18 +1990,18 @@ private void drawSASTLearnMore(DisplayModel selectedItem, TabFolder folder, TabI
19421990 final ScrolledComposite learnMoreScrolledComposite = new ScrolledComposite (folder , SWT .V_SCROLL );
19431991 learnMoreScrolledComposite .setExpandHorizontal (true );
19441992 learnMoreScrolledComposite .setExpandVertical (true );
1945-
1946- final Composite learnMoreComposite = new Composite (learnMoreScrolledComposite , SWT .NONE );
1947- learnMoreComposite .setLayout (new GridLayout ());
1948-
1949- learnMoreScrolledComposite .setContent (learnMoreComposite );
1950- learnMoreScrolledComposite .setMinSize (learnMoreComposite .computeSize (SWT .DEFAULT , SWT .DEFAULT ));
19511993
1952- if (learnMoreData == null ) {
1953- CLabel loadingLabel = new CLabel (learnMoreComposite , SWT .NONE );
1994+ final Composite learnMoreComposite = new Composite (learnMoreScrolledComposite , SWT .NONE );
1995+ learnMoreComposite .setLayout (new GridLayout ());
1996+
1997+ learnMoreScrolledComposite .setContent (learnMoreComposite );
1998+ learnMoreScrolledComposite .setMinSize (learnMoreComposite .computeSize (SWT .DEFAULT , SWT .DEFAULT ));
1999+
2000+ if (learnMoreData == null ) {
2001+ CLabel loadingLabel = new CLabel (learnMoreComposite , SWT .NONE );
19542002 loadingLabel .setText (PluginConstants .LEARN_MORE_LOADING );
1955- }
1956-
2003+ }
2004+
19572005 learnMoreTab .setControl (learnMoreScrolledComposite );
19582006
19592007 Job job = new Job (PluginConstants .GETTING_LEARN_MORE_JOB ) {
@@ -1987,8 +2035,8 @@ protected IStatus run(IProgressMonitor arg0) {
19872035 });
19882036 }
19892037
1990- learnMoreScrolledComposite .setMinSize (learnMoreComposite .computeSize (SWT .DEFAULT , SWT .DEFAULT ));
1991- learnMoreComposite .layout ();
2038+ learnMoreScrolledComposite .setMinSize (learnMoreComposite .computeSize (SWT .DEFAULT , SWT .DEFAULT ));
2039+ learnMoreComposite .layout ();
19922040 }
19932041 } catch (Exception e ) {
19942042 CxLogger .error (String .format (PluginConstants .ERROR_GETTING_LEARN_MORE , e .getMessage ()), e );
@@ -2036,17 +2084,17 @@ private void drawSASTRemediationExamples(DisplayModel selectedItem, TabFolder fo
20362084 final ScrolledComposite remediationExamplesScrolledComposite = new ScrolledComposite (folder , SWT .V_SCROLL | SWT .BORDER );
20372085 remediationExamplesScrolledComposite .setExpandHorizontal (true );
20382086 remediationExamplesScrolledComposite .setExpandVertical (true );
2039-
2040- final Composite remediationExamplesComposite = new Composite (remediationExamplesScrolledComposite , SWT .NONE );
2041- remediationExamplesComposite .setLayout (new GridLayout ());
2042-
2043- remediationExamplesScrolledComposite .setContent (remediationExamplesComposite );
2044- remediationExamplesScrolledComposite .setMinSize (remediationExamplesComposite .computeSize (SWT .DEFAULT , SWT .DEFAULT ));
20452087
2046- if (learnMoreData == null ) {
2047- Label loadingLabel = new Label (remediationExamplesComposite , SWT .NONE );
2088+ final Composite remediationExamplesComposite = new Composite (remediationExamplesScrolledComposite , SWT .NONE );
2089+ remediationExamplesComposite .setLayout (new GridLayout ());
2090+
2091+ remediationExamplesScrolledComposite .setContent (remediationExamplesComposite );
2092+ remediationExamplesScrolledComposite .setMinSize (remediationExamplesComposite .computeSize (SWT .DEFAULT , SWT .DEFAULT ));
2093+
2094+ if (learnMoreData == null ) {
2095+ Label loadingLabel = new Label (remediationExamplesComposite , SWT .NONE );
20482096 loadingLabel .setText (PluginConstants .LEARN_MORE_LOADING );
2049- }
2097+ }
20502098
20512099 remediationExamplesTab .setControl (remediationExamplesScrolledComposite );
20522100
@@ -2074,14 +2122,14 @@ protected IStatus run(IProgressMonitor arg0) {
20742122 for (Sample sample : samples ) {
20752123 StyledText sampleTitle = new StyledText (remediationExamplesComposite , SWT .WRAP );
20762124 sampleTitle .setText (String .format (PluginConstants .REMEDIATION_EXAMPLE_TITLE_FORMAT , sample .getTitle (), sample .getProgLanguage ()));
2077- GridData titleLayoutData = new GridData ( GridData .FILL_HORIZONTAL ) ;
2078- titleLayoutData .grabExcessHorizontalSpace = true ;
2079- titleLayoutData .horizontalAlignment = SWT .FILL ;
2080- titleLayoutData .widthHint = remediationExamplesScrolledComposite .getClientArea ().width - SCROLL_WIDTH ;
2081- titleLayoutData .horizontalSpan = 2 ;
2082- sampleTitle .setLayoutData (titleLayoutData );
2083- sampleTitle .setMargins (2 , 5 , 2 , 5 );
2084-
2125+ GridData titleLayoutData = new GridData ( GridData .FILL_HORIZONTAL ) ;
2126+ titleLayoutData .grabExcessHorizontalSpace = true ;
2127+ titleLayoutData .horizontalAlignment = SWT .FILL ;
2128+ titleLayoutData .widthHint = remediationExamplesScrolledComposite .getClientArea ().width - SCROLL_WIDTH ;
2129+ titleLayoutData .horizontalSpan = 2 ;
2130+ sampleTitle .setLayoutData (titleLayoutData );
2131+ sampleTitle .setMargins (2 , 5 , 2 , 5 );
2132+
20852133 Composite sampleExampleComposite = new Composite (remediationExamplesComposite , SWT .NONE );
20862134 sampleExampleComposite .setBackground (remediationExamplesComposite .getBackground ());
20872135 GridLayout layout = new GridLayout ();
@@ -2092,12 +2140,12 @@ protected IStatus run(IProgressMonitor arg0) {
20922140
20932141 Label sampleExample = new Label (sampleExampleComposite , SWT .WRAP );
20942142 sampleExample .setText (sample .getCode ());
2095- GridData exampleLayoutData = new GridData (GridData .FILL_HORIZONTAL ) ;
2096- exampleLayoutData .grabExcessHorizontalSpace = true ;
2097- exampleLayoutData .horizontalAlignment = SWT .FILL ;
2098- exampleLayoutData .widthHint = remediationExamplesScrolledComposite .getClientArea ().width - SCROLL_WIDTH ;
2099- exampleLayoutData .horizontalSpan = 2 ;
2100- sampleExample .setLayoutData (exampleLayoutData );
2143+ GridData exampleLayoutData = new GridData (GridData .FILL_HORIZONTAL ) ;
2144+ exampleLayoutData .grabExcessHorizontalSpace = true ;
2145+ exampleLayoutData .horizontalAlignment = SWT .FILL ;
2146+ exampleLayoutData .widthHint = remediationExamplesScrolledComposite .getClientArea ().width - SCROLL_WIDTH ;
2147+ exampleLayoutData .horizontalSpan = 2 ;
2148+ sampleExample .setLayoutData (exampleLayoutData );
21012149
21022150 remediationExamplesScrolledComposite .setMinSize (remediationExamplesComposite .computeSize (SWT .DEFAULT , SWT .DEFAULT ));
21032151 remediationExamplesComposite .layout ();
@@ -2146,14 +2194,14 @@ private void addLearnMoreSectionsToComposite(Composite composite, String title,
21462194 titleLabel .setFont (boldFont );
21472195
21482196 StyledText descriptionLabel = new StyledText (composite , SWT .WRAP );
2149- descriptionLabel .setText (description );
2150- GridData descriptionLayout = new GridData (GridData .FILL_HORIZONTAL );
2151- descriptionLayout .grabExcessHorizontalSpace = true ;
2152- descriptionLayout .horizontalAlignment = SWT .FILL ;
2153- descriptionLayout .widthHint = composite .getClientArea ().width - SCROLL_WIDTH ;
2154- descriptionLayout .horizontalSpan = 2 ;
2155- descriptionLabel .setLayoutData (descriptionLayout );
2156- descriptionLabel .setBottomMargin (20 );
2197+ descriptionLabel .setText (description );
2198+ GridData descriptionLayout = new GridData (GridData .FILL_HORIZONTAL );
2199+ descriptionLayout .grabExcessHorizontalSpace = true ;
2200+ descriptionLayout .horizontalAlignment = SWT .FILL ;
2201+ descriptionLayout .widthHint = composite .getClientArea ().width - SCROLL_WIDTH ;
2202+ descriptionLayout .horizontalSpan = 2 ;
2203+ descriptionLabel .setLayoutData (descriptionLayout );
2204+ descriptionLabel .setBottomMargin (20 );
21572205 }
21582206
21592207 /*private void populateBFLMessage(Image image, String bflMessage) {
@@ -2232,18 +2280,18 @@ protected IStatus run(IProgressMonitor arg0) {
22322280 private void drawVulnerabilityLocation (DisplayModel selectedItem ) {
22332281 ScrolledComposite sc = new ScrolledComposite (attackVectorCompositePanel , SWT .H_SCROLL | SWT .V_SCROLL );
22342282
2235- Composite child = new Composite (sc , SWT .NONE );
2236- child .setLayoutData (new GridData (GridData .FILL , GridData .BEGINNING , true , true ));
2237- child .setLayout (new GridLayout (1 , false ));
2238- child .setBackground (attackVectorCompositePanel .getBackground ());
2283+ Composite child = new Composite (sc , SWT .NONE );
2284+ child .setLayoutData (new GridData (GridData .FILL , GridData .BEGINNING , true , true ));
2285+ child .setLayout (new GridLayout (1 , false ));
2286+ child .setBackground (attackVectorCompositePanel .getBackground ());
22392287
2240- drawAttackVectorTitle (child , PluginConstants .LOCATION );
2288+ drawAttackVectorTitle (child , PluginConstants .LOCATION );
22412289 drawIndividualLocationData (child , selectedItem );
22422290
2243- sc .setContent (child );
2244- sc .setMinSize (child .computeSize (SWT .DEFAULT , SWT .DEFAULT ));
2245- sc .setExpandHorizontal (true );
2246- sc .setExpandVertical (true );
2291+ sc .setContent (child );
2292+ sc .setMinSize (child .computeSize (SWT .DEFAULT , SWT .DEFAULT ));
2293+ sc .setExpandHorizontal (true );
2294+ sc .setExpandVertical (true );
22472295 }
22482296
22492297 private void drawIndividualLocationData (Composite parent , DisplayModel selectedItem ) {
0 commit comments