]> granicus.if.org Git - icu/commitdiff
ICU-10993 Fix line ending errors
authorMichael Ow <mow@svn.icu-project.org>
Wed, 2 Jul 2014 23:05:28 +0000 (23:05 +0000)
committerMichael Ow <mow@svn.icu-project.org>
Wed, 2 Jul 2014 23:05:28 +0000 (23:05 +0000)
X-SVN-Rev: 35990

.gitattributes
icu4j/tools/build/src/com/ibm/icu/dev/tool/docs/DeprecatedAPIChecker.java

index 91edd7a55b9e357ed72050b7b39138a1766b780c..55a1b1ce37530da85b6688702e886d7fb3c76235 100644 (file)
@@ -261,7 +261,6 @@ icu4j/main/classes/core/.settings/edu.umd.cs.findbugs.core.prefs -text
 icu4j/main/classes/core/.settings/org.eclipse.core.resources.prefs -text
 icu4j/main/classes/core/.settings/org.eclipse.jdt.core.prefs -text
 icu4j/main/classes/core/manifest.stub -text
-icu4j/main/classes/core/src/com/ibm/icu/text/ScientificFormatHelper.java -text
 icu4j/main/classes/currdata/.externalToolBuilders/copy-data-currdata.launch -text
 icu4j/main/classes/currdata/.settings/org.eclipse.core.resources.prefs -text
 icu4j/main/classes/currdata/.settings/org.eclipse.jdt.core.prefs -text
@@ -322,7 +321,6 @@ icu4j/main/tests/core/manifest.stub -text
 icu4j/main/tests/core/src/com/ibm/icu/dev/data/rbbi/english.dict -text
 icu4j/main/tests/core/src/com/ibm/icu/dev/data/resources/testmessages.properties -text
 icu4j/main/tests/core/src/com/ibm/icu/dev/data/thai6.ucs -text
-icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/ScientificFormatHelperTest.java -text
 icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.impl.OlsonTimeZone.dat -text
 icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.impl.TimeZoneAdapter.dat -text
 icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.math.BigDecimal.dat -text
@@ -617,7 +615,6 @@ icu4j/tools/build/icu4j51.api3.gz -text
 icu4j/tools/build/icu4j52.api3.gz -text
 icu4j/tools/build/icu4j53.api3.gz -text
 icu4j/tools/build/manifest.stub -text
-icu4j/tools/build/src/com/ibm/icu/dev/tool/docs/DeprecatedAPIChecker.java -text
 icu4j/tools/misc/.settings/org.eclipse.core.resources.prefs -text
 icu4j/tools/misc/manifest.stub -text
 tools/currency/.classpath -text
index ea8d07d54d0774053d829a7db89e32b657d4794f..50ba0aca91762110d9c2dd61fc2078de5d259203 100644 (file)
-/*\r
- *******************************************************************************\r
- * Copyright (C) 2014, International Business Machines Corporation and         *\r
- * others. All Rights Reserved.                                                *\r
- *******************************************************************************\r
- */\r
-package com.ibm.icu.dev.tool.docs;\r
-\r
-import java.io.File;\r
-import java.io.PrintWriter;\r
-import java.lang.reflect.Constructor;\r
-import java.lang.reflect.Field;\r
-import java.lang.reflect.GenericArrayType;\r
-import java.lang.reflect.Method;\r
-import java.lang.reflect.Modifier;\r
-import java.lang.reflect.ParameterizedType;\r
-import java.lang.reflect.Type;\r
-import java.lang.reflect.TypeVariable;\r
-import java.lang.reflect.WildcardType;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Map.Entry;\r
-import java.util.Set;\r
-import java.util.TreeMap;\r
-\r
-public class DeprecatedAPIChecker {\r
-\r
-    public static void main(String[] args) {\r
-        if (args.length != 1) {\r
-            System.err.println("Illegal command argument. Specify the API signature file path.");\r
-        }\r
-        // Load the ICU4J API signature file\r
-        Set<APIInfo> apiInfoSet = APIData.read(new File(args[0]), true).getAPIInfoSet();\r
-\r
-        DeprecatedAPIChecker checker = new DeprecatedAPIChecker(apiInfoSet, new PrintWriter(System.err, true));\r
-        checker.checkDeprecated();\r
-        System.exit(checker.errCount);\r
-    }\r
-\r
-    private int errCount = 0;\r
-    private Set<APIInfo> apiInfoSet;\r
-    private PrintWriter pw;\r
-\r
-    public DeprecatedAPIChecker(Set<APIInfo> apiInfoSet, PrintWriter pw) {\r
-        this.apiInfoSet = apiInfoSet;\r
-        this.pw = pw;\r
-    }\r
-\r
-    public int errorCount() {\r
-        return errCount;\r
-    }\r
-\r
-    public void checkDeprecated() {\r
-        // Gather API class/enum names and its names that can be\r
-        // used for Class.forName()\r
-        Map<String, String> apiClassNameMap = new TreeMap<String, String>();\r
-        for (APIInfo api : apiInfoSet) {\r
-            if (!api.isPublic() && !api.isProtected()) {\r
-                continue;\r
-            }\r
-            if (!api.isClass() && !api.isEnum()) {\r
-                continue;\r
-            }\r
-            String packageName = api.getPackageName();\r
-            String className = api.getName();\r
-\r
-            // Replacing separator for nested class/enum (replacing '.' with\r
-            // '$'), so we can use the name for Class.forName(String)\r
-            String classNamePath = className.contains(".") ? className.replace('.', '$') : className;\r
-\r
-            apiClassNameMap.put(packageName + "." + classNamePath, packageName + "." + className);\r
-        }\r
-\r
-        // Walk through API classes using reflection\r
-        for (Entry<String, String> classEntry : apiClassNameMap.entrySet()) {\r
-            String classNamePath = classEntry.getKey();\r
-            try {\r
-                Class<?> cls = Class.forName(classNamePath);\r
-                if (cls.isEnum()) {\r
-                    checkEnum(cls, apiClassNameMap);\r
-                } else {\r
-                    checkClass(cls, apiClassNameMap);\r
-                }\r
-            } catch (ClassNotFoundException e) {\r
-                pw.println("## Error ## Class " + classNamePath + " is not found.");\r
-                errCount++;\r
-            }\r
-        }\r
-    }\r
-\r
-    private void checkClass(Class<?> cls, Map<String, String> clsNameMap) {\r
-        assert !cls.isEnum();\r
-\r
-        String clsPath = cls.getName();\r
-        String clsName = clsNameMap.get(clsPath);\r
-        APIInfo api = null;\r
-\r
-        if (clsName != null) {\r
-            api = findClassInfo(apiInfoSet, clsName);\r
-        }\r
-        if (api == null) {\r
-            pw.println("## Error ## Class " + clsName + " is not found in the API signature data.");\r
-            errCount++;\r
-        }\r
-\r
-        // check class\r
-        compareDeprecated(isAPIDeprecated(api), cls.isAnnotationPresent(Deprecated.class), clsName, null, "Class");\r
-\r
-        // check fields\r
-        for (Field f : cls.getDeclaredFields()) {\r
-            if (!isPublicOrProtected(f.getModifiers())) {\r
-                continue;\r
-            }\r
-\r
-            String fName = f.getName();\r
-            api = findFieldInfo(apiInfoSet, clsName, fName);\r
-            if (api == null) {\r
-                pw.println("## Error ## Field " + clsName + "." + fName + " is not found in the API signature data.");\r
-                errCount++;\r
-                continue;\r
-            }\r
-\r
-            compareDeprecated(isAPIDeprecated(api), f.isAnnotationPresent(Deprecated.class), clsName, fName, "Field");\r
-        }\r
-\r
-        // check constructors\r
-        for (Constructor<?> ctor : cls.getDeclaredConstructors()) {\r
-            if (!isPublicOrProtected(ctor.getModifiers())) {\r
-                continue;\r
-            }\r
-\r
-            List<String> paramNames = getParamNames(ctor);\r
-            api = findConstructorInfo(apiInfoSet, clsName, paramNames);\r
-\r
-            if (api == null) {\r
-                pw.println("## Error ## Constructor " + clsName + formatParams(paramNames)\r
-                        + " is not found in the API signature data.");\r
-                errCount++;\r
-                continue;\r
-            }\r
-\r
-            compareDeprecated(isAPIDeprecated(api), ctor.isAnnotationPresent(Deprecated.class), clsName,\r
-                    api.getClassName() + formatParams(paramNames), "Constructor");\r
-        }\r
-\r
-        // check methods\r
-        for (Method mtd : cls.getDeclaredMethods()) {\r
-            // Note: We exclude synthetic method.\r
-            if (!isPublicOrProtected(mtd.getModifiers()) || mtd.isSynthetic()) {\r
-                continue;\r
-            }\r
-\r
-            String mtdName = mtd.getName();\r
-            List<String> paramNames = getParamNames(mtd);\r
-            api = findMethodInfo(apiInfoSet, clsName, mtdName, paramNames);\r
-\r
-            if (api == null) {\r
-                pw.println("## Error ## Method " + clsName + "#" + mtdName + formatParams(paramNames)\r
-                        + " is not found in the API signature data.");\r
-                errCount++;\r
-                continue;\r
-            }\r
-\r
-            compareDeprecated(isAPIDeprecated(api), mtd.isAnnotationPresent(Deprecated.class), clsName, mtdName\r
-                    + formatParams(paramNames), "Method");\r
-\r
-        }\r
-    }\r
-\r
-    private void checkEnum(Class<?> cls, Map<String, String> clsNameMap) {\r
-        assert cls.isEnum();\r
-\r
-        String enumPath = cls.getName();\r
-        String enumName = clsNameMap.get(enumPath);\r
-        APIInfo api = null;\r
-\r
-        if (enumName != null) {\r
-            api = findEnumInfo(apiInfoSet, enumName);\r
-        }\r
-        if (api == null) {\r
-            pw.println("## Error ## Enum " + enumName + " is not found in the API signature data.");\r
-            errCount++;\r
-        }\r
-\r
-        // check enum\r
-        compareDeprecated(isAPIDeprecated(api), cls.isAnnotationPresent(Deprecated.class), enumName, null, "Enum");\r
-\r
-        // check enum constants\r
-        for (Field ec : cls.getDeclaredFields()) {\r
-            if (!ec.isEnumConstant()) {\r
-                continue;\r
-            }\r
-            String ecName = ec.getName();\r
-            api = findEnumConstantInfo(apiInfoSet, enumName, ecName);\r
-            if (api == null) {\r
-                pw.println("## Error ## Enum constant " + enumName + "." + ecName\r
-                        + " is not found in the API signature data.");\r
-                errCount++;\r
-                continue;\r
-            }\r
-\r
-            compareDeprecated(isAPIDeprecated(api), ec.isAnnotationPresent(Deprecated.class), enumName, ecName,\r
-                    "Enum Constant");\r
-        }\r
-\r
-        // check methods\r
-        for (Method mtd : cls.getDeclaredMethods()) {\r
-            // Note: We exclude built-in methods in a Java Enum instance\r
-            if (!isPublicOrProtected(mtd.getModifiers()) || isBuiltinEnumMethod(mtd)) {\r
-                continue;\r
-            }\r
-\r
-            String mtdName = mtd.getName();\r
-            List<String> paramNames = getParamNames(mtd);\r
-            api = findMethodInfo(apiInfoSet, enumName, mtdName, paramNames);\r
-\r
-            if (api == null) {\r
-                pw.println("## Error ## Method " + enumName + "#" + mtdName + formatParams(paramNames)\r
-                        + " is not found in the API signature data.");\r
-                errCount++;\r
-                continue;\r
-            }\r
-\r
-            compareDeprecated(isAPIDeprecated(api), mtd.isAnnotationPresent(Deprecated.class), enumName, mtdName\r
-                    + formatParams(paramNames), "Method");\r
-\r
-        }\r
-    }\r
-\r
-    private void compareDeprecated(boolean depTag, boolean depAnt, String cls, String name, String type) {\r
-        if (depTag != depAnt) {\r
-            String apiName = cls;\r
-            if (name != null) {\r
-                apiName += "." + name;\r
-            }\r
-            if (depTag) {\r
-                pw.println("No @Deprecated annotation: [" + type + "] " + apiName);\r
-            } else {\r
-                pw.println("No @deprecated JavaDoc tag: [" + type + "] " + apiName);\r
-            }\r
-            errCount++;\r
-        }\r
-    }\r
-\r
-    private static boolean isPublicOrProtected(int modifier) {\r
-        return ((modifier & Modifier.PUBLIC) != 0) || ((modifier & Modifier.PROTECTED) != 0);\r
-    }\r
-\r
-    // Check if a method is automatically generated for a each Enum\r
-    private static boolean isBuiltinEnumMethod(Method mtd) {\r
-        // Just check method name for now\r
-        String name = mtd.getName();\r
-        return name.equals("values") || name.equals("valueOf");\r
-    }\r
-\r
-    private static boolean isAPIDeprecated(APIInfo api) {\r
-        return api.isDeprecated() || api.isInternal() || api.isObsolete();\r
-    }\r
-\r
-    private static APIInfo findClassInfo(Set<APIInfo> apis, String cls) {\r
-        for (APIInfo api : apis) {\r
-            String clsName = api.getPackageName() + "." + api.getName();\r
-            if (api.isClass() && clsName.equals(cls)) {\r
-                return api;\r
-            }\r
-        }\r
-        return null;\r
-    }\r
-\r
-    private static APIInfo findFieldInfo(Set<APIInfo> apis, String cls, String field) {\r
-        for (APIInfo api : apis) {\r
-            String clsName = api.getPackageName() + "." + api.getClassName();\r
-            if (api.isField() && clsName.equals(cls) && api.getName().equals(field)) {\r
-                return api;\r
-            }\r
-        }\r
-        return null;\r
-    }\r
-\r
-    private static APIInfo findConstructorInfo(Set<APIInfo> apis, String cls, List<String> params) {\r
-        for (APIInfo api : apis) {\r
-            String clsName = api.getPackageName() + "." + api.getClassName();\r
-            if (api.isConstructor() && clsName.equals(cls)) {\r
-                // check params\r
-                List<String> paramsFromApi = getParamNames(api);\r
-                if (paramsFromApi.size() == params.size()) {\r
-                    boolean match = true;\r
-                    for (int i = 0; i < params.size(); i++) {\r
-                        if (!params.get(i).equals(paramsFromApi.get(i))) {\r
-                            match = false;\r
-                            break;\r
-                        }\r
-                    }\r
-                    if (match) {\r
-                        return api;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return null;\r
-    }\r
-\r
-    private static APIInfo findMethodInfo(Set<APIInfo> apis, String cls, String method, List<String> params) {\r
-        for (APIInfo api : apis) {\r
-            String clsName = api.getPackageName() + "." + api.getClassName();\r
-            if (api.isMethod() && clsName.equals(cls) && api.getName().equals(method)) {\r
-                // check params\r
-                List<String> paramsFromApi = getParamNames(api);\r
-                if (paramsFromApi.size() == params.size()) {\r
-                    boolean match = true;\r
-                    for (int i = 0; i < params.size(); i++) {\r
-                        if (!params.get(i).equals(paramsFromApi.get(i))) {\r
-                            match = false;\r
-                            break;\r
-                        }\r
-                    }\r
-                    if (match) {\r
-                        return api;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return null;\r
-    }\r
-\r
-    private static APIInfo findEnumInfo(Set<APIInfo> apis, String ecls) {\r
-        for (APIInfo api : apis) {\r
-            String clsName = api.getPackageName() + "." + api.getName();\r
-            if (api.isEnum() && clsName.equals(ecls)) {\r
-                return api;\r
-            }\r
-        }\r
-        return null;\r
-    }\r
-\r
-    private static APIInfo findEnumConstantInfo(Set<APIInfo> apis, String ecls, String econst) {\r
-        for (APIInfo api : apis) {\r
-            String clsName = api.getPackageName() + "." + api.getClassName();\r
-            if (api.isEnumConstant() && clsName.equals(ecls) && api.getName().equals(econst)) {\r
-                return api;\r
-            }\r
-        }\r
-        return null;\r
-    }\r
-\r
-    private static List<String> getParamNames(APIInfo api) {\r
-        if (!api.isMethod() && !api.isConstructor()) {\r
-            throw new IllegalArgumentException(api.toString() + " is not a constructor or a method.");\r
-        }\r
-\r
-        List<String> nameList = new ArrayList<String>();\r
-        String signature = api.getSignature();\r
-        int start = signature.indexOf('(');\r
-        int end = signature.indexOf(')');\r
-\r
-        if (start < 0 || end < 0 || start > end) {\r
-            throw new RuntimeException(api.toString() + " has bad API signature: " + signature);\r
-        }\r
-\r
-        String paramsSegment = signature.substring(start + 1, end);\r
-        // erase generic args\r
-        if (paramsSegment.indexOf('<') >= 0) {\r
-            StringBuilder buf = new StringBuilder();\r
-            boolean inGenericsParams = false;\r
-            for (int i = 0; i < paramsSegment.length(); i++) {\r
-                char c = paramsSegment.charAt(i);\r
-                if (inGenericsParams) {\r
-                    if (c == '>') {\r
-                        inGenericsParams = false;\r
-                    }\r
-                } else {\r
-                    if (c == '<') {\r
-                        inGenericsParams = true;\r
-                    } else {\r
-                        buf.append(c);\r
-                    }\r
-                }\r
-            }\r
-            paramsSegment = buf.toString();\r
-        }\r
-\r
-        if (paramsSegment.length() > 0) {\r
-            String[] params = paramsSegment.split("\\s*,\\s*");\r
-            for (String p : params) {\r
-                if (p.endsWith("...")) {\r
-                    // varargs to array\r
-                    p = p.substring(0, p.length() - 3) + "[]";\r
-                }\r
-                nameList.add(p);\r
-            }\r
-        }\r
-\r
-        return nameList;\r
-    }\r
-\r
-    private static List<String> getParamNames(Constructor<?> ctor) {\r
-        return toTypeNameList(ctor.getGenericParameterTypes());\r
-    }\r
-\r
-    private static List<String> getParamNames(Method method) {\r
-        return toTypeNameList(method.getGenericParameterTypes());\r
-    }\r
-\r
-    private static final String[] PRIMITIVES = { "byte", "short", "int", "long", "float", "double", "boolean", "char" };\r
-    private static char[] PRIMITIVE_SIGNATURES = { 'B', 'S', 'I', 'J', 'F', 'D', 'Z', 'C' };\r
-\r
-    private static List<String> toTypeNameList(Type[] types) {\r
-        List<String> nameList = new ArrayList<String>();\r
-\r
-        for (Type t : types) {\r
-            StringBuilder s = new StringBuilder();\r
-            if (t instanceof ParameterizedType) {\r
-                // throw away generics parameters\r
-                ParameterizedType prdType = (ParameterizedType) t;\r
-                Class<?> rawType = (Class<?>) prdType.getRawType();\r
-                s.append(rawType.getCanonicalName());\r
-            } else if (t instanceof WildcardType) {\r
-                // we don't need to worry about WildcardType,\r
-                // because this tool erases generics parameters\r
-                // for comparing method/constructor parameters\r
-                throw new RuntimeException("WildcardType not supported by this tool");\r
-            } else if (t instanceof TypeVariable) {\r
-                // this tool does not try to resolve actual parameter\r
-                // type - for example, "<T extends Object> void foo(T in)"\r
-                // this tool just use the type variable "T" for API signature\r
-                // comparison. This is actually not perfect, but should be\r
-                // sufficient for our purpose.\r
-                TypeVariable<?> tVar = (TypeVariable<?>) t;\r
-                s.append(tVar.getName());\r
-            } else if (t instanceof GenericArrayType) {\r
-                // same as TypeVariable. "T[]" is sufficient enough.\r
-                GenericArrayType tGenArray = (GenericArrayType) t;\r
-                s.append(tGenArray.toString());\r
-            } else if (t instanceof Class) {\r
-                Class<?> tClass = (Class<?>) t;\r
-                String tName = tClass.getCanonicalName();\r
-\r
-                if (tName.charAt(0) == '[') {\r
-                    // Array type\r
-                    int idx = 0;\r
-                    for (; idx < tName.length(); idx++) {\r
-                        if (tName.charAt(idx) != '[') {\r
-                            break;\r
-                        }\r
-                    }\r
-                    int dimension = idx;\r
-                    char sigChar = tName.charAt(dimension);\r
-\r
-                    String elemType = null;\r
-                    if (sigChar == 'L') {\r
-                        // class\r
-                        elemType = tName.substring(dimension + 1, tName.length() - 1);\r
-                    } else {\r
-                        // primitive\r
-                        for (int i = 0; i < PRIMITIVE_SIGNATURES.length; i++) {\r
-                            if (sigChar == PRIMITIVE_SIGNATURES[i]) {\r
-                                elemType = PRIMITIVES[i];\r
-                                break;\r
-                            }\r
-                        }\r
-                    }\r
-\r
-                    if (elemType == null) {\r
-                        throw new RuntimeException("Unexpected array type: " + tName);\r
-                    }\r
-\r
-                    s.append(elemType);\r
-                    for (int i = 0; i < dimension; i++) {\r
-                        s.append("[]");\r
-                    }\r
-                } else {\r
-                    s.append(tName);\r
-                }\r
-            } else {\r
-                throw new IllegalArgumentException("Unknown type: " + t);\r
-            }\r
-\r
-            nameList.add(s.toString());\r
-        }\r
-\r
-        return nameList;\r
-    }\r
-\r
-    private static String formatParams(List<String> paramNames) {\r
-        StringBuilder buf = new StringBuilder("(");\r
-        boolean isFirst = true;\r
-        for (String p : paramNames) {\r
-            if (isFirst) {\r
-                isFirst = false;\r
-            } else {\r
-                buf.append(", ");\r
-            }\r
-            buf.append(p);\r
-        }\r
-        buf.append(")");\r
-\r
-        return buf.toString();\r
-    }\r
-}\r
+/*
+ *******************************************************************************
+ * Copyright (C) 2014, International Business Machines Corporation and         *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ */
+package com.ibm.icu.dev.tool.docs;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+
+public class DeprecatedAPIChecker {
+
+    public static void main(String[] args) {
+        if (args.length != 1) {
+            System.err.println("Illegal command argument. Specify the API signature file path.");
+        }
+        // Load the ICU4J API signature file
+        Set<APIInfo> apiInfoSet = APIData.read(new File(args[0]), true).getAPIInfoSet();
+
+        DeprecatedAPIChecker checker = new DeprecatedAPIChecker(apiInfoSet, new PrintWriter(System.err, true));
+        checker.checkDeprecated();
+        System.exit(checker.errCount);
+    }
+
+    private int errCount = 0;
+    private Set<APIInfo> apiInfoSet;
+    private PrintWriter pw;
+
+    public DeprecatedAPIChecker(Set<APIInfo> apiInfoSet, PrintWriter pw) {
+        this.apiInfoSet = apiInfoSet;
+        this.pw = pw;
+    }
+
+    public int errorCount() {
+        return errCount;
+    }
+
+    public void checkDeprecated() {
+        // Gather API class/enum names and its names that can be
+        // used for Class.forName()
+        Map<String, String> apiClassNameMap = new TreeMap<String, String>();
+        for (APIInfo api : apiInfoSet) {
+            if (!api.isPublic() && !api.isProtected()) {
+                continue;
+            }
+            if (!api.isClass() && !api.isEnum()) {
+                continue;
+            }
+            String packageName = api.getPackageName();
+            String className = api.getName();
+
+            // Replacing separator for nested class/enum (replacing '.' with
+            // '$'), so we can use the name for Class.forName(String)
+            String classNamePath = className.contains(".") ? className.replace('.', '$') : className;
+
+            apiClassNameMap.put(packageName + "." + classNamePath, packageName + "." + className);
+        }
+
+        // Walk through API classes using reflection
+        for (Entry<String, String> classEntry : apiClassNameMap.entrySet()) {
+            String classNamePath = classEntry.getKey();
+            try {
+                Class<?> cls = Class.forName(classNamePath);
+                if (cls.isEnum()) {
+                    checkEnum(cls, apiClassNameMap);
+                } else {
+                    checkClass(cls, apiClassNameMap);
+                }
+            } catch (ClassNotFoundException e) {
+                pw.println("## Error ## Class " + classNamePath + " is not found.");
+                errCount++;
+            }
+        }
+    }
+
+    private void checkClass(Class<?> cls, Map<String, String> clsNameMap) {
+        assert !cls.isEnum();
+
+        String clsPath = cls.getName();
+        String clsName = clsNameMap.get(clsPath);
+        APIInfo api = null;
+
+        if (clsName != null) {
+            api = findClassInfo(apiInfoSet, clsName);
+        }
+        if (api == null) {
+            pw.println("## Error ## Class " + clsName + " is not found in the API signature data.");
+            errCount++;
+        }
+
+        // check class
+        compareDeprecated(isAPIDeprecated(api), cls.isAnnotationPresent(Deprecated.class), clsName, null, "Class");
+
+        // check fields
+        for (Field f : cls.getDeclaredFields()) {
+            if (!isPublicOrProtected(f.getModifiers())) {
+                continue;
+            }
+
+            String fName = f.getName();
+            api = findFieldInfo(apiInfoSet, clsName, fName);
+            if (api == null) {
+                pw.println("## Error ## Field " + clsName + "." + fName + " is not found in the API signature data.");
+                errCount++;
+                continue;
+            }
+
+            compareDeprecated(isAPIDeprecated(api), f.isAnnotationPresent(Deprecated.class), clsName, fName, "Field");
+        }
+
+        // check constructors
+        for (Constructor<?> ctor : cls.getDeclaredConstructors()) {
+            if (!isPublicOrProtected(ctor.getModifiers())) {
+                continue;
+            }
+
+            List<String> paramNames = getParamNames(ctor);
+            api = findConstructorInfo(apiInfoSet, clsName, paramNames);
+
+            if (api == null) {
+                pw.println("## Error ## Constructor " + clsName + formatParams(paramNames)
+                        + " is not found in the API signature data.");
+                errCount++;
+                continue;
+            }
+
+            compareDeprecated(isAPIDeprecated(api), ctor.isAnnotationPresent(Deprecated.class), clsName,
+                    api.getClassName() + formatParams(paramNames), "Constructor");
+        }
+
+        // check methods
+        for (Method mtd : cls.getDeclaredMethods()) {
+            // Note: We exclude synthetic method.
+            if (!isPublicOrProtected(mtd.getModifiers()) || mtd.isSynthetic()) {
+                continue;
+            }
+
+            String mtdName = mtd.getName();
+            List<String> paramNames = getParamNames(mtd);
+            api = findMethodInfo(apiInfoSet, clsName, mtdName, paramNames);
+
+            if (api == null) {
+                pw.println("## Error ## Method " + clsName + "#" + mtdName + formatParams(paramNames)
+                        + " is not found in the API signature data.");
+                errCount++;
+                continue;
+            }
+
+            compareDeprecated(isAPIDeprecated(api), mtd.isAnnotationPresent(Deprecated.class), clsName, mtdName
+                    + formatParams(paramNames), "Method");
+
+        }
+    }
+
+    private void checkEnum(Class<?> cls, Map<String, String> clsNameMap) {
+        assert cls.isEnum();
+
+        String enumPath = cls.getName();
+        String enumName = clsNameMap.get(enumPath);
+        APIInfo api = null;
+
+        if (enumName != null) {
+            api = findEnumInfo(apiInfoSet, enumName);
+        }
+        if (api == null) {
+            pw.println("## Error ## Enum " + enumName + " is not found in the API signature data.");
+            errCount++;
+        }
+
+        // check enum
+        compareDeprecated(isAPIDeprecated(api), cls.isAnnotationPresent(Deprecated.class), enumName, null, "Enum");
+
+        // check enum constants
+        for (Field ec : cls.getDeclaredFields()) {
+            if (!ec.isEnumConstant()) {
+                continue;
+            }
+            String ecName = ec.getName();
+            api = findEnumConstantInfo(apiInfoSet, enumName, ecName);
+            if (api == null) {
+                pw.println("## Error ## Enum constant " + enumName + "." + ecName
+                        + " is not found in the API signature data.");
+                errCount++;
+                continue;
+            }
+
+            compareDeprecated(isAPIDeprecated(api), ec.isAnnotationPresent(Deprecated.class), enumName, ecName,
+                    "Enum Constant");
+        }
+
+        // check methods
+        for (Method mtd : cls.getDeclaredMethods()) {
+            // Note: We exclude built-in methods in a Java Enum instance
+            if (!isPublicOrProtected(mtd.getModifiers()) || isBuiltinEnumMethod(mtd)) {
+                continue;
+            }
+
+            String mtdName = mtd.getName();
+            List<String> paramNames = getParamNames(mtd);
+            api = findMethodInfo(apiInfoSet, enumName, mtdName, paramNames);
+
+            if (api == null) {
+                pw.println("## Error ## Method " + enumName + "#" + mtdName + formatParams(paramNames)
+                        + " is not found in the API signature data.");
+                errCount++;
+                continue;
+            }
+
+            compareDeprecated(isAPIDeprecated(api), mtd.isAnnotationPresent(Deprecated.class), enumName, mtdName
+                    + formatParams(paramNames), "Method");
+
+        }
+    }
+
+    private void compareDeprecated(boolean depTag, boolean depAnt, String cls, String name, String type) {
+        if (depTag != depAnt) {
+            String apiName = cls;
+            if (name != null) {
+                apiName += "." + name;
+            }
+            if (depTag) {
+                pw.println("No @Deprecated annotation: [" + type + "] " + apiName);
+            } else {
+                pw.println("No @deprecated JavaDoc tag: [" + type + "] " + apiName);
+            }
+            errCount++;
+        }
+    }
+
+    private static boolean isPublicOrProtected(int modifier) {
+        return ((modifier & Modifier.PUBLIC) != 0) || ((modifier & Modifier.PROTECTED) != 0);
+    }
+
+    // Check if a method is automatically generated for a each Enum
+    private static boolean isBuiltinEnumMethod(Method mtd) {
+        // Just check method name for now
+        String name = mtd.getName();
+        return name.equals("values") || name.equals("valueOf");
+    }
+
+    private static boolean isAPIDeprecated(APIInfo api) {
+        return api.isDeprecated() || api.isInternal() || api.isObsolete();
+    }
+
+    private static APIInfo findClassInfo(Set<APIInfo> apis, String cls) {
+        for (APIInfo api : apis) {
+            String clsName = api.getPackageName() + "." + api.getName();
+            if (api.isClass() && clsName.equals(cls)) {
+                return api;
+            }
+        }
+        return null;
+    }
+
+    private static APIInfo findFieldInfo(Set<APIInfo> apis, String cls, String field) {
+        for (APIInfo api : apis) {
+            String clsName = api.getPackageName() + "." + api.getClassName();
+            if (api.isField() && clsName.equals(cls) && api.getName().equals(field)) {
+                return api;
+            }
+        }
+        return null;
+    }
+
+    private static APIInfo findConstructorInfo(Set<APIInfo> apis, String cls, List<String> params) {
+        for (APIInfo api : apis) {
+            String clsName = api.getPackageName() + "." + api.getClassName();
+            if (api.isConstructor() && clsName.equals(cls)) {
+                // check params
+                List<String> paramsFromApi = getParamNames(api);
+                if (paramsFromApi.size() == params.size()) {
+                    boolean match = true;
+                    for (int i = 0; i < params.size(); i++) {
+                        if (!params.get(i).equals(paramsFromApi.get(i))) {
+                            match = false;
+                            break;
+                        }
+                    }
+                    if (match) {
+                        return api;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private static APIInfo findMethodInfo(Set<APIInfo> apis, String cls, String method, List<String> params) {
+        for (APIInfo api : apis) {
+            String clsName = api.getPackageName() + "." + api.getClassName();
+            if (api.isMethod() && clsName.equals(cls) && api.getName().equals(method)) {
+                // check params
+                List<String> paramsFromApi = getParamNames(api);
+                if (paramsFromApi.size() == params.size()) {
+                    boolean match = true;
+                    for (int i = 0; i < params.size(); i++) {
+                        if (!params.get(i).equals(paramsFromApi.get(i))) {
+                            match = false;
+                            break;
+                        }
+                    }
+                    if (match) {
+                        return api;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private static APIInfo findEnumInfo(Set<APIInfo> apis, String ecls) {
+        for (APIInfo api : apis) {
+            String clsName = api.getPackageName() + "." + api.getName();
+            if (api.isEnum() && clsName.equals(ecls)) {
+                return api;
+            }
+        }
+        return null;
+    }
+
+    private static APIInfo findEnumConstantInfo(Set<APIInfo> apis, String ecls, String econst) {
+        for (APIInfo api : apis) {
+            String clsName = api.getPackageName() + "." + api.getClassName();
+            if (api.isEnumConstant() && clsName.equals(ecls) && api.getName().equals(econst)) {
+                return api;
+            }
+        }
+        return null;
+    }
+
+    private static List<String> getParamNames(APIInfo api) {
+        if (!api.isMethod() && !api.isConstructor()) {
+            throw new IllegalArgumentException(api.toString() + " is not a constructor or a method.");
+        }
+
+        List<String> nameList = new ArrayList<String>();
+        String signature = api.getSignature();
+        int start = signature.indexOf('(');
+        int end = signature.indexOf(')');
+
+        if (start < 0 || end < 0 || start > end) {
+            throw new RuntimeException(api.toString() + " has bad API signature: " + signature);
+        }
+
+        String paramsSegment = signature.substring(start + 1, end);
+        // erase generic args
+        if (paramsSegment.indexOf('<') >= 0) {
+            StringBuilder buf = new StringBuilder();
+            boolean inGenericsParams = false;
+            for (int i = 0; i < paramsSegment.length(); i++) {
+                char c = paramsSegment.charAt(i);
+                if (inGenericsParams) {
+                    if (c == '>') {
+                        inGenericsParams = false;
+                    }
+                } else {
+                    if (c == '<') {
+                        inGenericsParams = true;
+                    } else {
+                        buf.append(c);
+                    }
+                }
+            }
+            paramsSegment = buf.toString();
+        }
+
+        if (paramsSegment.length() > 0) {
+            String[] params = paramsSegment.split("\\s*,\\s*");
+            for (String p : params) {
+                if (p.endsWith("...")) {
+                    // varargs to array
+                    p = p.substring(0, p.length() - 3) + "[]";
+                }
+                nameList.add(p);
+            }
+        }
+
+        return nameList;
+    }
+
+    private static List<String> getParamNames(Constructor<?> ctor) {
+        return toTypeNameList(ctor.getGenericParameterTypes());
+    }
+
+    private static List<String> getParamNames(Method method) {
+        return toTypeNameList(method.getGenericParameterTypes());
+    }
+
+    private static final String[] PRIMITIVES = { "byte", "short", "int", "long", "float", "double", "boolean", "char" };
+    private static char[] PRIMITIVE_SIGNATURES = { 'B', 'S', 'I', 'J', 'F', 'D', 'Z', 'C' };
+
+    private static List<String> toTypeNameList(Type[] types) {
+        List<String> nameList = new ArrayList<String>();
+
+        for (Type t : types) {
+            StringBuilder s = new StringBuilder();
+            if (t instanceof ParameterizedType) {
+                // throw away generics parameters
+                ParameterizedType prdType = (ParameterizedType) t;
+                Class<?> rawType = (Class<?>) prdType.getRawType();
+                s.append(rawType.getCanonicalName());
+            } else if (t instanceof WildcardType) {
+                // we don't need to worry about WildcardType,
+                // because this tool erases generics parameters
+                // for comparing method/constructor parameters
+                throw new RuntimeException("WildcardType not supported by this tool");
+            } else if (t instanceof TypeVariable) {
+                // this tool does not try to resolve actual parameter
+                // type - for example, "<T extends Object> void foo(T in)"
+                // this tool just use the type variable "T" for API signature
+                // comparison. This is actually not perfect, but should be
+                // sufficient for our purpose.
+                TypeVariable<?> tVar = (TypeVariable<?>) t;
+                s.append(tVar.getName());
+            } else if (t instanceof GenericArrayType) {
+                // same as TypeVariable. "T[]" is sufficient enough.
+                GenericArrayType tGenArray = (GenericArrayType) t;
+                s.append(tGenArray.toString());
+            } else if (t instanceof Class) {
+                Class<?> tClass = (Class<?>) t;
+                String tName = tClass.getCanonicalName();
+
+                if (tName.charAt(0) == '[') {
+                    // Array type
+                    int idx = 0;
+                    for (; idx < tName.length(); idx++) {
+                        if (tName.charAt(idx) != '[') {
+                            break;
+                        }
+                    }
+                    int dimension = idx;
+                    char sigChar = tName.charAt(dimension);
+
+                    String elemType = null;
+                    if (sigChar == 'L') {
+                        // class
+                        elemType = tName.substring(dimension + 1, tName.length() - 1);
+                    } else {
+                        // primitive
+                        for (int i = 0; i < PRIMITIVE_SIGNATURES.length; i++) {
+                            if (sigChar == PRIMITIVE_SIGNATURES[i]) {
+                                elemType = PRIMITIVES[i];
+                                break;
+                            }
+                        }
+                    }
+
+                    if (elemType == null) {
+                        throw new RuntimeException("Unexpected array type: " + tName);
+                    }
+
+                    s.append(elemType);
+                    for (int i = 0; i < dimension; i++) {
+                        s.append("[]");
+                    }
+                } else {
+                    s.append(tName);
+                }
+            } else {
+                throw new IllegalArgumentException("Unknown type: " + t);
+            }
+
+            nameList.add(s.toString());
+        }
+
+        return nameList;
+    }
+
+    private static String formatParams(List<String> paramNames) {
+        StringBuilder buf = new StringBuilder("(");
+        boolean isFirst = true;
+        for (String p : paramNames) {
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                buf.append(", ");
+            }
+            buf.append(p);
+        }
+        buf.append(")");
+
+        return buf.toString();
+    }
+}