1 /* 2 * Copyright (C) 2011 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 package com.android.cts.javascannerdoclet; 17 18 import java.io.BufferedWriter; 19 import java.io.File; 20 import java.io.FileNotFoundException; 21 import java.io.FileOutputStream; 22 import java.io.FileWriter; 23 import java.io.IOException; 24 import java.io.OutputStream; 25 import java.io.PrintWriter; 26 import java.util.ArrayList; 27 import java.util.Collection; 28 import java.util.Iterator; 29 30 import javax.xml.parsers.DocumentBuilderFactory; 31 import javax.xml.parsers.ParserConfigurationException; 32 import javax.xml.transform.Transformer; 33 import javax.xml.transform.TransformerException; 34 import javax.xml.transform.TransformerFactory; 35 import javax.xml.transform.TransformerFactoryConfigurationError; 36 import javax.xml.transform.dom.DOMSource; 37 import javax.xml.transform.stream.StreamResult; 38 39 import org.w3c.dom.Attr; 40 import org.w3c.dom.Document; 41 import org.w3c.dom.Node; 42 import org.w3c.dom.NodeList; 43 44 import com.sun.javadoc.AnnotationDesc; 45 import com.sun.javadoc.AnnotationTypeDoc; 46 import com.sun.javadoc.AnnotationValue; 47 import com.sun.javadoc.ClassDoc; 48 import com.sun.javadoc.Doclet; 49 import com.sun.javadoc.MethodDoc; 50 import com.sun.javadoc.RootDoc; 51 import com.sun.javadoc.AnnotationDesc.ElementValuePair; 52 import com.sun.javadoc.AnnotationTypeElementDoc; 53 54 /** 55 * Doclet that outputs in the following format: 56 * 57 * suite:android.holo.cts 58 * case:HoloTest 59 * test:testHolo 60 * test:testHoloDialog 61 */ 62 public class CtsJavaScannerDoclet extends Doclet { 63 64 private static final String JUNIT4_TEST_ANNOTATION = "org.junit.Test"; 65 66 static final String JUNIT_TEST_CASE_CLASS_NAME = "junit.framework.testcase"; 67 private static final String SUPPRESS_ANNOTATION = 68 "android.test.suitebuilder.annotation.Suppress"; 69 start(RootDoc root)70 public static boolean start(RootDoc root) { 71 ClassDoc[] classes = root.classes(); 72 if (classes == null) { 73 return false; 74 } 75 76 PrintWriter writer = new PrintWriter(System.out); 77 78 for (ClassDoc clazz : classes) { 79 if (clazz.isAbstract()) { 80 continue; 81 } 82 83 final boolean isJUnit3 = isJUnit3TestCase(clazz); 84 if (!isJUnit3 && !isJUnit4TestClass(clazz)) { 85 continue; 86 } 87 88 writer.append("suite:").println(clazz.containingPackage().name()); 89 writer.append("case:").println(clazz.name()); 90 for (; clazz != null; clazz = clazz.superclass()) { 91 for (MethodDoc method : clazz.methods()) { 92 int timeout = -1; 93 if (isJUnit3) { 94 if (!method.name().startsWith("test")) { 95 continue; 96 } 97 98 boolean suppressed = false; 99 AnnotationDesc[] annotations = method.annotations(); 100 for (AnnotationDesc annot : annotations) { 101 String atype = annot.annotationType().toString(); 102 if (atype.equals(SUPPRESS_ANNOTATION)) { 103 suppressed = true; 104 } 105 } 106 if (suppressed) { 107 continue; 108 } 109 } else { 110 /* JUnit4 */ 111 boolean isTest = false; 112 113 for (AnnotationDesc annot : method.annotations()) { 114 if (annot.annotationType().toString().equals(JUNIT4_TEST_ANNOTATION)) { 115 isTest = true; 116 117 for (ElementValuePair pair : annot.elementValues()) { 118 if (pair.element().name().equals("timeout")) { 119 /* JUnit4 timeouts are in milliseconds. */ 120 timeout = (int) (((Long) pair.value().value()) / 60000L); 121 } 122 } 123 } 124 } 125 126 if (!isTest) { 127 continue; 128 } 129 } 130 131 writer.append("test:"); 132 if (timeout >= 0) { 133 writer.append(method.name()).println(":" + timeout); 134 } else { 135 writer.println(method.name()); 136 } 137 } 138 } 139 } 140 141 writer.close(); 142 return true; 143 } 144 isJUnit3TestCase(ClassDoc clazz)145 private static boolean isJUnit3TestCase(ClassDoc clazz) { 146 while((clazz = clazz.superclass()) != null) { 147 if (JUNIT_TEST_CASE_CLASS_NAME.equals(clazz.qualifiedName().toLowerCase())) { 148 return true; 149 } 150 } 151 return false; 152 } 153 isJUnit4TestClass(ClassDoc clazz)154 private static boolean isJUnit4TestClass(ClassDoc clazz) { 155 for (MethodDoc method : clazz.methods()) { 156 for (AnnotationDesc annot : method.annotations()) { 157 if (annot.annotationType().toString().equals(JUNIT4_TEST_ANNOTATION)) { 158 return true; 159 } 160 } 161 } 162 return false; 163 } 164 } 165