/** * Validates a potential package name and returns null if the package name is valid, and otherwise * returns a description for why it is not valid. * <p> * Note that Android package names are more restrictive than general Java package names; * we require at least two segments, limit the character set to [a-zA-Z0-9_] (Java allows any * {@link Character#isLetter(char)} and require that each segment start with a letter (Java allows * underscores at the beginning). * <p> * For details, see core/java/android/content/pm/PackageParser.java#validateName * * @param name the package name * @return null if the package is valid as an Android package name, and otherwise a description for why not */ @Nullable public static String validateAndroidPackageName(@NotNull String name) { if (name.isEmpty()) { return "Package name is missing"; } String packageManagerCheck = validateName(name, true); if (packageManagerCheck != null) { return packageManagerCheck; } // In addition, we have to check that none of the segments are Java identifiers, since // that will lead to compilation errors, which the package manager doesn't need to worry about // (the code wouldn't have compiled) ApplicationManager.getApplication().assertReadAccessAllowed(); Lexer lexer = JavaParserDefinition.createLexer(LanguageLevel.JDK_1_5); int index = 0; while (true) { int index1 = name.indexOf('.', index); if (index1 < 0) { index1 = name.length(); } String segment = name.substring(index, index1); lexer.start(segment); if (lexer.getTokenType() != JavaTokenType.IDENTIFIER) { if (lexer.getTokenType() instanceof IKeywordElementType) { return "Package names cannot contain Java keywords like '" + segment + "'"; } if (segment.isEmpty()) { return "Package segments must be of non-zero length"; } return segment + " is not a valid identifier"; } if (index1 == name.length()) { break; } index = index1 + 1; } return null; }