Path: blob/master/src/java.base/share/classes/jdk/internal/module/Checks.java
41159 views
/*1* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package jdk.internal.module;2627import java.util.Set;2829/**30* Utility class for checking module, package, and class names.31*/3233public final class Checks {3435private Checks() { }3637/**38* Checks a name to ensure that it's a legal module name.39*40* @throws IllegalArgumentException if name is null or not a legal41* module name42*/43public static String requireModuleName(String name) {44if (name == null)45throw new IllegalArgumentException("Null module name");46int next;47int off = 0;48while ((next = name.indexOf('.', off)) != -1) {49String id = name.substring(off, next);50if (!isJavaIdentifier(id)) {51throw new IllegalArgumentException(name + ": Invalid module name"52+ ": '" + id + "' is not a Java identifier");53}54off = next+1;55}56String last = name.substring(off);57if (!isJavaIdentifier(last)) {58throw new IllegalArgumentException(name + ": Invalid module name"59+ ": '" + last + "' is not a Java identifier");60}61return name;62}6364/**65* Checks a name to ensure that it's a legal package name.66*67* @throws IllegalArgumentException if name is null or not a legal68* package name69*/70public static String requirePackageName(String name) {71return requireTypeName("package name", name);72}7374/**75* Returns {@code true} if the given name is a legal package name.76*/77public static boolean isPackageName(String name) {78return isTypeName(name);79}8081/**82* Checks a name to ensure that it's a legal qualified class name83*84* @throws IllegalArgumentException if name is null or not a legal85* qualified class name86*/87public static String requireServiceTypeName(String name) {88return requireQualifiedClassName("service type name", name);89}9091/**92* Checks a name to ensure that it's a legal qualified class name.93*94* @throws IllegalArgumentException if name is null or not a legal95* qualified class name96*/97public static String requireServiceProviderName(String name) {98return requireQualifiedClassName("service provider name", name);99}100101/**102* Checks a name to ensure that it's a legal qualified class name in103* a named package.104*105* @throws IllegalArgumentException if name is null or not a legal106* qualified class name in a named package107*/108public static String requireQualifiedClassName(String what, String name) {109requireTypeName(what, name);110if (name.indexOf('.') == -1)111throw new IllegalArgumentException(name + ": is not a qualified name of"112+ " a Java class in a named package");113return name;114}115116/**117* Returns {@code true} if the given name is a legal class name.118*/119public static boolean isClassName(String name) {120return isTypeName(name);121}122123/**124* Returns {@code true} if the given name is a legal type name.125*/126private static boolean isTypeName(String name) {127int next;128int off = 0;129while ((next = name.indexOf('.', off)) != -1) {130String id = name.substring(off, next);131if (!isJavaIdentifier(id))132return false;133off = next+1;134}135String last = name.substring(off);136return isJavaIdentifier(last);137}138139/**140* Checks if the given name is a legal type name.141*142* @throws IllegalArgumentException if name is null or not a legal143* type name144*/145private static String requireTypeName(String what, String name) {146if (name == null)147throw new IllegalArgumentException("Null " + what);148int next;149int off = 0;150while ((next = name.indexOf('.', off)) != -1) {151String id = name.substring(off, next);152if (!isJavaIdentifier(id)) {153throw new IllegalArgumentException(name + ": Invalid " + what154+ ": '" + id + "' is not a Java identifier");155}156off = next + 1;157}158String last = name.substring(off);159if (!isJavaIdentifier(last)) {160throw new IllegalArgumentException(name + ": Invalid " + what161+ ": '" + last + "' is not a Java identifier");162}163return name;164}165166/**167* Returns true if the given string is a legal Java identifier,168* otherwise false.169*/170private static boolean isJavaIdentifier(String str) {171if (str.isEmpty() || RESERVED.contains(str))172return false;173174int first = Character.codePointAt(str, 0);175if (!Character.isJavaIdentifierStart(first))176return false;177178int i = Character.charCount(first);179while (i < str.length()) {180int cp = Character.codePointAt(str, i);181if (!Character.isJavaIdentifierPart(cp))182return false;183i += Character.charCount(cp);184}185186return true;187}188189// keywords, boolean and null literals, not allowed in identifiers190private static final Set<String> RESERVED = Set.of(191"abstract",192"assert",193"boolean",194"break",195"byte",196"case",197"catch",198"char",199"class",200"const",201"continue",202"default",203"do",204"double",205"else",206"enum",207"extends",208"final",209"finally",210"float",211"for",212"goto",213"if",214"implements",215"import",216"instanceof",217"int",218"interface",219"long",220"native",221"new",222"package",223"private",224"protected",225"public",226"return",227"short",228"static",229"strictfp",230"super",231"switch",232"synchronized",233"this",234"throw",235"throws",236"transient",237"try",238"void",239"volatile",240"while",241"true",242"false",243"null",244"_"245);246}247248249