11/*******************************************************************************
2- * Copyright (c) 2017 Microsoft Corporation and others.
2+ * Copyright (c) 2017-2021 Microsoft Corporation and others.
33 * All rights reserved. This program and the accompanying materials
44 * are made available under the terms of the Eclipse Public License v1.0
55 * which accompanies this distribution, and is available at
2222import java .util .logging .Logger ;
2323import java .util .stream .Collectors ;
2424
25+ import javax .lang .model .SourceVersion ;
26+
2527import org .apache .commons .lang3 .StringUtils ;
2628import org .eclipse .core .resources .IFile ;
2729import org .eclipse .core .resources .IFolder ;
4749
4850public class ResolveMainClassHandler {
4951 private static final Logger logger = Logger .getLogger (Configuration .LOGGER_NAME );
50- // Java command line supports two kinds of main class format: <mainclass> and <module>[/<mainclass>]
51- private static final String CLASSNAME_REGX = "([$\\ w]+\\ .)*[$\\ w]+(/([$\\ w]+\\ .)*[$\\ w]+)?" ;
52+ private static final int CONFIGERROR_INVALID_CLASS_NAME = 1 ;
53+ private static final int CONFIGERROR_MAIN_CLASS_NOT_EXIST = 2 ;
54+ private static final int CONFIGERROR_MAIN_CLASS_NOT_UNIQUE = 3 ;
55+ private static final int CONFIGERROR_INVALID_JAVA_PROJECT = 4 ;
5256
5357 /**
5458 * resolve main class and project name.
@@ -185,23 +189,41 @@ private ValidationResponse validateLaunchConfigCore(List<Object> arguments) thro
185189 private ValidationResult validateMainClass (final String mainClass , final String projectName , boolean containsExternalClasspaths ) throws CoreException {
186190 if (StringUtils .isEmpty (mainClass )) {
187191 return new ValidationResult (true );
188- } else if (!mainClass .matches (CLASSNAME_REGX )) {
189- return new ValidationResult (false , String .format ("ConfigError: '%s' is not a valid class name." , mainClass ));
192+ } else if (!isValidMainClassName (mainClass )) {
193+ return new ValidationResult (false , String .format ("ConfigError: '%s' is not a valid class name." , mainClass ),
194+ CONFIGERROR_INVALID_CLASS_NAME );
190195 }
191196
192197 if (!containsExternalClasspaths && StringUtils .isEmpty (projectName )) {
193198 List <IJavaProject > javaProjects = searchClassInProjectClasspaths (mainClass );
194199 if (javaProjects .size () == 0 ) {
195- return new ValidationResult (false , String .format ("ConfigError: Main class '%s' doesn't exist in the workspace." , mainClass ));
200+ return new ValidationResult (false , String .format ("ConfigError: Main class '%s' doesn't exist in the workspace." , mainClass ),
201+ CONFIGERROR_MAIN_CLASS_NOT_EXIST );
196202 }
197203 if (javaProjects .size () > 1 ) {
198- return new ValidationResult (false , String .format ("ConfigError: Main class '%s' isn't unique in the workspace." , mainClass ));
204+ return new ValidationResult (false , String .format ("ConfigError: Main class '%s' isn't unique in the workspace." , mainClass ),
205+ CONFIGERROR_MAIN_CLASS_NOT_UNIQUE );
199206 }
200207 }
201208
202209 return new ValidationResult (true );
203210 }
204211
212+ // Java command line supports two kinds of main class format: <mainclass> and <module>[/<mainclass>]
213+ private boolean isValidMainClassName (String mainClass ) {
214+ if (StringUtils .isEmpty (mainClass )) {
215+ return true ;
216+ }
217+
218+ int index = mainClass .indexOf ('/' );
219+ if (index == -1 ) {
220+ return SourceVersion .isName (mainClass );
221+ }
222+
223+ return SourceVersion .isName (mainClass .substring (0 , index ))
224+ && SourceVersion .isName (mainClass .substring (index + 1 ));
225+ }
226+
205227 private List <IJavaProject > searchClassInProjectClasspaths (String fullyQualifiedClassName ) throws CoreException {
206228 return ResolveClasspathsHandler .getJavaProjectFromType (fullyQualifiedClassName );
207229 }
@@ -212,7 +234,8 @@ private ValidationResult validateProjectName(final String mainClass, final Strin
212234 }
213235
214236 if (JdtUtils .getJavaProject (projectName ) == null ) {
215- return new ValidationResult (false , String .format ("ConfigError: The project '%s' is not a valid java project." , projectName ));
237+ return new ValidationResult (false , String .format ("ConfigError: The project '%s' is not a valid java project." , projectName ),
238+ CONFIGERROR_INVALID_JAVA_PROJECT );
216239 }
217240
218241 return new ValidationResult (true );
@@ -302,14 +325,16 @@ class ValidationResponse {
302325 class ValidationResult {
303326 boolean isValid ;
304327 String message ;
328+ int kind ;
305329
306330 ValidationResult (boolean isValid ) {
307331 this .isValid = isValid ;
308332 }
309333
310- ValidationResult (boolean isValid , String message ) {
334+ ValidationResult (boolean isValid , String message , int kind ) {
311335 this .isValid = isValid ;
312336 this .message = message ;
337+ this .kind = kind ;
313338 }
314339 }
315340}
0 commit comments