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[:timeout_value] 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 start(RootDoc root)68 public static boolean start(RootDoc root) { 69 ClassDoc[] classes = root.classes(); 70 if (classes == null) { 71 return false; 72 } 73 74 PrintWriter writer = new PrintWriter(System.out); 75 76 for (ClassDoc clazz : classes) { 77 if (clazz.isAbstract()) { 78 continue; 79 } 80 81 final boolean isJUnit3 = isJUnit3TestCase(clazz); 82 if (!isJUnit3 && !isJUnit4TestClass(clazz)) { 83 continue; 84 } 85 86 writer.append("suite:").println(clazz.containingPackage().name()); 87 writer.append("case:").println(clazz.name()); 88 for (; clazz != null; clazz = clazz.superclass()) { 89 for (MethodDoc method : clazz.methods()) { 90 int timeout = -1; 91 if (isJUnit3) { 92 if (!method.name().startsWith("test")) { 93 continue; 94 } 95 96 AnnotationDesc[] annotations = method.annotations(); 97 for (AnnotationDesc annot : annotations) { 98 String atype = annot.annotationType().toString(); 99 if (atype.equals("com.android.cts.util.TimeoutReq")) { 100 ElementValuePair[] cpairs = annot.elementValues(); 101 for (ElementValuePair pair : cpairs) { 102 AnnotationTypeElementDoc elem = pair.element(); 103 AnnotationValue value = pair.value(); 104 if (elem.name().equals("minutes")) { 105 timeout = ((Integer) value.value()); 106 } 107 } 108 } 109 } 110 } else { 111 /* JUnit4 */ 112 boolean isTest = false; 113 114 for (AnnotationDesc annot : method.annotations()) { 115 if (annot.annotationType().toString().equals(JUNIT4_TEST_ANNOTATION)) { 116 isTest = true; 117 118 for (ElementValuePair pair : annot.elementValues()) { 119 if (pair.element().name().equals("timeout")) { 120 /* JUnit4 timeouts are in milliseconds. */ 121 timeout = (int) (((Long) pair.value().value()) / 60000L); 122 } 123 } 124 } 125 } 126 127 if (!isTest) { 128 continue; 129 } 130 } 131 132 writer.append("test:"); 133 if (timeout >= 0) { 134 writer.append(method.name()).println(":" + timeout); 135 } else { 136 writer.println(method.name()); 137 } 138 } 139 } 140 } 141 142 writer.close(); 143 return true; 144 } 145 isJUnit3TestCase(ClassDoc clazz)146 private static boolean isJUnit3TestCase(ClassDoc clazz) { 147 while((clazz = clazz.superclass()) != null) { 148 if (JUNIT_TEST_CASE_CLASS_NAME.equals(clazz.qualifiedName().toLowerCase())) { 149 return true; 150 } 151 } 152 return false; 153 } 154 isJUnit4TestClass(ClassDoc clazz)155 private static boolean isJUnit4TestClass(ClassDoc clazz) { 156 for (MethodDoc method : clazz.methods()) { 157 for (AnnotationDesc annot : method.annotations()) { 158 if (annot.annotationType().toString().equals(JUNIT4_TEST_ANNOTATION)) { 159 return true; 160 } 161 } 162 } 163 return false; 164 } 165 } 166