1 package org.unicode.cldr.tool; 2 3 import java.io.FileNotFoundException; 4 import java.io.IOException; 5 import java.lang.reflect.Method; 6 7 import org.unicode.cldr.util.CLDRFile; 8 import org.unicode.cldr.util.CLDRTool; 9 10 /** 11 * 12 * Implement a 'main' for the CLDR jar. 13 */ 14 @CLDRTool(alias = "main", description = "The 'main' class invoked when java -jar or doubleclicking the jar.", hidden = "Hidden so as not to list itself", 15 url = Main.TOOLSURL) 16 class Main { 17 private static final String CLASS_SUFFIX = ".class"; 18 private static final String MAIN = "main"; 19 public static final String TOOLSURL = "http://cldr.unicode.org/tools/"; 20 main(String args[])21 public static void main(String args[]) throws Throwable { 22 if (args.length == 0) { 23 System.out.println("Usage: [ -l | [class|alias] args ...]"); 24 System.out.println("Example usage:"); 25 System.out.println(" (java -jar cldr.jar ) -l -- prints a list of ALL tool/util/test classes with a 'main()' function."); 26 System.out.println(" (java -jar cldr.jar ) org.unicode.cldr.util.XMLValidator somefile.xml ..."); 27 System.out.println(" (java -jar cldr.jar ) validate somefile.xml ..."); 28 System.out.println("For more info: " + TOOLSURL); 29 System.out.println("CLDRFile.GEN_VERSION=" + CLDRFile.GEN_VERSION); 30 System.out.println("(Use the -l option to list hidden/undocumented tools)"); 31 System.out.println(); 32 listClasses(false, null); 33 } else if (args.length == 1 && args[0].equals("-l")) { 34 listClasses(true, null); 35 } else { 36 final String mainClass = args[0]; 37 final String args2[] = new String[args.length - 1]; 38 System.arraycopy(args, 1, args2, 0, args2.length); 39 Class<?> c = null; 40 41 try { 42 c = Class.forName(mainClass); 43 } catch (ClassNotFoundException e) { 44 // not found 45 } 46 if (c == null) { 47 c = listClasses(false, mainClass); 48 } 49 if (c == null) { 50 throw new IllegalArgumentException("Class not found and not an alias: " + mainClass); 51 } 52 53 if (c == Main.class) { 54 throw new IllegalArgumentException("Cowardly refusing to invoke myself recursively. Stop."); 55 } 56 57 final java.lang.reflect.Method main = getStaticMain(c); 58 59 System.err.println(">> " + c.getName()); 60 61 main.invoke(null, (Object) args2); 62 } 63 } 64 65 /** 66 * @param showAll if true, include even hidden classes 67 * @param match if non-null, will return the class instead of listing it 68 * @throws IOException 69 * @throws FileNotFoundException 70 */ listClasses(boolean showAll, final String match)71 public static Class<?> listClasses(boolean showAll, final String match) throws IOException, FileNotFoundException { 72 final java.util.jar.JarInputStream jis = getJarInputStream(); 73 final ClassLoader classLoader = Main.class.getClassLoader(); 74 if (jis == null) { 75 return null; 76 } 77 java.util.jar.JarEntry je; 78 while ((je = jis.getNextJarEntry()) != null) { 79 final String name = je.getName(); 80 if (inOuterClass(name)) { 81 final String className = filenameToClassName(name); 82 try { 83 final Class<?> c = java.lang.Class.forName(className, false, classLoader); 84 85 if ((match != null) && showAll == false && !c.isAnnotationPresent(CLDRTool.class)) 86 continue; 87 88 Method method = getStaticMain(c); 89 90 if (method != null) { // skip classes w/o static method - even if they have an annotatoin. 91 CLDRTool annotation = c.getAnnotation(CLDRTool.class); 92 93 if (match == null) { 94 // list mode 95 if (showAll || 96 (annotation != null && annotation.hidden().length() == 0)) { 97 98 if (annotation != null) { 99 System.out.println("" + annotation.alias() + " - " + annotation.description()); 100 if (annotation.url().length() > 0) { 101 System.out.println(" <" + annotation.url() + ">"); 102 } else { 103 System.out.println(" <" + TOOLSURL + annotation.alias() + ">"); 104 } 105 System.out.println(" = " + className); 106 if (annotation.hidden().length() > 0) { 107 System.out.println(" HIDDEN: " + annotation.hidden()); 108 } 109 System.out.println(); 110 } else { 111 System.out.print(" " + className); 112 System.out.println(" (no @CLDRTool annotation)"); 113 } 114 } 115 } else { 116 if (match.equalsIgnoreCase(className)) { 117 return c; // match the classname 118 } 119 if (annotation != null && 120 annotation.alias().length() > 0 && 121 match.equalsIgnoreCase(annotation.alias())) { 122 return c; // match the alias 123 } 124 } 125 } 126 } catch (Throwable t) { 127 // ignore uninstantiable. 128 //System.out.println(t); 129 } 130 } 131 } 132 return null; // not found or not needed. 133 } 134 135 /** 136 * @param c 137 * @return 138 * @throws NoSuchMethodException 139 */ getStaticMain(final Class<?> c)140 public static Method getStaticMain(final Class<?> c) throws NoSuchMethodException { 141 return c.getMethod(MAIN, String[].class); 142 } 143 144 /** 145 * @param name 146 * @return 147 */ filenameToClassName(final String name)148 public static String filenameToClassName(final String name) { 149 return name.substring(0, name.length() - (CLASS_SUFFIX.length())) 150 .replaceAll("/", "."); 151 } 152 153 /** 154 * @param name 155 * @return 156 */ inOuterClass(final String name)157 public static boolean inOuterClass(final String name) { 158 return name.endsWith(CLASS_SUFFIX) && 159 !name.contains("$"); 160 } 161 162 /** 163 * @return 164 * @throws IOException 165 * @throws FileNotFoundException 166 */ getJarInputStream()167 public static java.util.jar.JarInputStream getJarInputStream() throws IOException, FileNotFoundException { 168 final java.net.URL url = Main.class.getProtectionDomain().getCodeSource().getLocation(); 169 if (!url.getPath().endsWith(".jar")) { 170 System.out.println("(Not inside a .jar file - no listing available.)"); 171 return null; 172 } 173 if (false) System.out.println("Classes in " + url.getPath()); 174 final java.util.jar.JarInputStream jis = new java.util.jar.JarInputStream(new java.io.FileInputStream(url.getPath())); 175 java.util.jar.JarEntry je = null; 176 return jis; 177 } 178 } 179