1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.compatibility.common.scanner; 18 19 import com.android.compatibility.common.util.KeyValueArgsParser; 20 21 import java.io.BufferedReader; 22 import java.io.File; 23 import java.io.FileFilter; 24 import java.io.InputStreamReader; 25 import java.util.ArrayList; 26 import java.util.Arrays; 27 import java.util.HashMap; 28 import java.util.List; 29 30 /** 31 * Scans a source directory for java tests and outputs a list of test classes and methods. 32 */ 33 public class JavaScanner { 34 35 static final String[] SOURCE_PATHS = { 36 "./frameworks/base/core/java", 37 "./frameworks/base/test-runner/src", 38 "./external/junit/src", 39 "./development/tools/hosttestlib/src", 40 "./libcore/dalvik/src/main/java", 41 "./common/device-side/util/src", 42 "./common/host-side/tradefed/src", 43 "./common/util/src" 44 }; 45 static final String[] CLASS_PATHS = { 46 "./prebuilts/misc/common/tradefed/tradefed-prebuilt.java", 47 "./prebuilts/misc/common/ub-uiautomator/ub-uiautomator.java" 48 }; 49 private final File mSourceDir; 50 private final File mDocletDir; 51 52 /** 53 * @param sourceDir The directory holding the source to scan. 54 * @param docletDir The directory holding the doclet (or its jar). 55 */ JavaScanner(File sourceDir, File docletDir)56 JavaScanner(File sourceDir, File docletDir) { 57 this.mSourceDir = sourceDir; 58 this.mDocletDir = docletDir; 59 } 60 scan()61 int scan() throws Exception { 62 final ArrayList<String> args = new ArrayList<String>(); 63 args.add("javadoc"); 64 args.add("-doclet"); 65 args.add("com.android.compatibility.common.scanner.JavaScannerDoclet"); 66 args.add("-sourcepath"); 67 args.add(getSourcePath(mSourceDir)); 68 args.add("-classpath"); 69 args.add(getClassPath()); 70 args.add("-docletpath"); 71 args.add(mDocletDir.toString()); 72 args.addAll(getSourceFiles(mSourceDir)); 73 74 // Dont want p to get blocked due to a full pipe. 75 final Process p = new ProcessBuilder(args).redirectErrorStream(true).start(); 76 final BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); 77 try { 78 String line = null; 79 while ((line = in.readLine()) != null) { 80 if (line.startsWith("suite:") || 81 line.startsWith("case:") || 82 line.startsWith("test:")) { 83 System.out.println(line); 84 } 85 } 86 } finally { 87 if (in != null) { 88 in.close(); 89 } 90 } 91 92 return p.waitFor(); 93 } 94 getSourcePath(File sourceDir)95 private static String getSourcePath(File sourceDir) { 96 final ArrayList<String> sourcePath = new ArrayList<String>(Arrays.asList(SOURCE_PATHS)); 97 sourcePath.add(sourceDir.toString()); 98 return join(sourcePath, ":"); 99 } 100 getClassPath()101 private static String getClassPath() { 102 return join(Arrays.asList(CLASS_PATHS), ":"); 103 } 104 getSourceFiles(File sourceDir)105 private static ArrayList<String> getSourceFiles(File sourceDir) { 106 final ArrayList<String> sourceFiles = new ArrayList<String>(); 107 final File[] files = sourceDir.listFiles(new FileFilter() { 108 public boolean accept(File pathname) { 109 return pathname.isDirectory() || pathname.toString().endsWith(".java"); 110 } 111 }); 112 for (File f : files) { 113 if (f.isDirectory()) { 114 sourceFiles.addAll(getSourceFiles(f)); 115 } else { 116 sourceFiles.add(f.toString()); 117 } 118 } 119 return sourceFiles; 120 } 121 join(List<String> list, String delimiter)122 private static String join(List<String> list, String delimiter) { 123 final StringBuilder builder = new StringBuilder(); 124 for (String s : list) { 125 builder.append(s); 126 builder.append(delimiter); 127 } 128 // Adding the delimiter each time and then removing the last one at the end is more 129 // efficient than doing a check in each iteration of the loop. 130 return builder.substring(0, builder.length() - delimiter.length()); 131 } 132 main(String[] args)133 public static void main(String[] args) throws Exception { 134 final HashMap<String, String> argsMap = KeyValueArgsParser.parse(args); 135 final String sourcePath = argsMap.get("-s"); 136 final String docletPath = argsMap.get("-d"); 137 if (sourcePath == null || docletPath == null) { 138 usage(args); 139 } 140 System.exit(new JavaScanner(new File(sourcePath), new File(docletPath)).scan()); 141 } 142 usage(String[] args)143 private static void usage(String[] args) { 144 System.err.println("Arguments: " + Arrays.toString(args)); 145 System.err.println("Usage: javascanner -s SOURCE_DIR -d DOCLET_PATH"); 146 System.exit(1); 147 } 148 } 149