001    /*
002     * Licensed under the Apache License, Version 2.0 (the "License");
003     * you may not use this file except in compliance with the License.
004     * You may obtain a copy of the License at
005     *
006     *      http://www.apache.org/licenses/LICENSE-2.0
007     *
008     * Unless required by applicable law or agreed to in writing, software
009     * distributed under the License is distributed on an "AS IS" BASIS,
010     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011     * See the License for the specific language governing permissions and
012     * limitations under the License.
013     */
014    package org.apache.commons.classscan.builtin;
015    
016    import java.util.regex.Matcher;
017    import java.util.regex.Pattern;
018    
019    /**
020     * Classname helper methods
021     */
022    public final class ClassNameHelper {
023            private ClassNameHelper() {
024            }
025    
026        private static final String IDENTIFIER_REGEX = "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*";
027        private static final String FILE_REGEX = "(" + IDENTIFIER_REGEX + ")\\.class";
028    
029        private static final String PATH_REGEX = "((" + IDENTIFIER_REGEX + "/)*)" + FILE_REGEX;
030        private static Pattern pathPattern = Pattern.compile(PATH_REGEX);
031    
032        /**
033         * Check if supplied path name is a valid pathed file name. The path must
034         * contain valid package names, the file name must be a valid Class name,
035         * and must be followed by ".class"
036         * 
037         * @param path
038         *            A file name with path
039         * @return The class name without the trailing ".class", with the dotted
040         *         package prefix, or null if the supplied filename is invalid
041         */
042        public static String getCannonicalClassNameFromPathName(String path) {
043            Matcher m = pathPattern.matcher(path);
044            if (m.matches()) {
045                String packagePrefix = m.group(1).replace('/', '.');
046                String className = m.group(3);
047                return packagePrefix + className;
048            }
049            else {
050                return null;
051            }
052        }
053    
054        private static Pattern IDENTIFIER_PACKAGE = Pattern.compile(IDENTIFIER_REGEX);
055    
056        /**
057         * Check if supplied name is a valid java package name portion or class
058         * identifier.
059         * 
060         * @param identifier
061         *            The name of a package file
062         * @return true if the identifier is a valid part of a package or class name
063         */
064        public static boolean isValidIdentifier(String identifier) {
065            Matcher ipm = IDENTIFIER_PACKAGE.matcher(identifier);
066            return ipm.matches();
067        }
068    
069        private static Pattern filePattern = Pattern.compile(FILE_REGEX);
070    
071        /**
072         * Check if supplied file name is a valid class file name. The name must be
073         * a valid Class name followed by ".class"
074         * 
075         * @param fileName
076         *            The name of a file (without path)
077         * @return The class name without the trailing ".class", or null if the
078         *         supplied filename is invalid
079         */
080        public static String getClassNameFromFileName(String fileName) {
081            Matcher fpm = filePattern.matcher(fileName);
082            if (fpm.matches()) {
083                return fpm.group(1);
084            }
085            else {
086                return null;
087            }
088        }
089    
090        /**
091         * Get the canonical name from the internal name
092         * 
093         * @param internalName
094         *            The internal name in the form Ljava/lang/Object;
095         * @return The canonical name in the form java.lang.Object
096         */
097        public static String internalToCanonicalName(String internalName) {
098            return internalName.substring(1, internalName.length() - 1).replace('/', '.');
099        }
100    }