1 /* 2 * Copyright (C) 2009 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 signature.converter.doclet; 18 19 import java.io.File; 20 import java.io.FileWriter; 21 import java.io.IOException; 22 import java.io.PrintWriter; 23 import java.io.StringWriter; 24 import java.lang.reflect.Constructor; 25 import java.util.HashSet; 26 import java.util.Set; 27 28 import signature.converter.Visibility; 29 import signature.converter.doclet.DocletToSigConverter; 30 import signature.converter.util.CompilationUnit; 31 import signature.model.IApi; 32 import signature.model.util.ModelUtil; 33 34 import com.sun.javadoc.RootDoc; 35 import com.sun.tools.javac.util.Context; 36 import com.sun.tools.javac.util.ListBuffer; 37 import com.sun.tools.javac.util.Options; 38 import com.sun.tools.javadoc.JavadocTool; 39 import com.sun.tools.javadoc.Messager; 40 import com.sun.tools.javadoc.ModifierFilter; 41 import com.sun.tools.javadoc.RootDocImpl; 42 43 public class DocletTestConverter extends signature.converter.util.AbstractTestSourceConverter { 44 45 static String sourcepath; 46 static String separator; 47 48 static { 49 separator = System.getProperty("file.separator"); 50 51 sourcepath = System.getProperty("java.io.tmpdir"); 52 sourcepath = sourcepath + separator + "cts" + separator; 53 System.out.println(">> "+sourcepath); 54 } 55 56 public IApi convert(Visibility visibility, Set<CompilationUnit> units) throws IOException { 57 try { 58 Set<String> packages = new HashSet<String>(); 59 for(CompilationUnit u : units){ 60 putSource(u); 61 String p = ModelUtil.getPackageName(u.getName()); 62 assert p.length() > 0 : "default package not supported by doclets"; 63 packages.add(p); 64 } 65 66 RootDoc root = getRootDoc(visibility, packages); 67 68 DocletToSigConverter converter = new DocletToSigConverter(); 69 70 IApi api = converter.convertDocletRoot("Doclet Test", root, visibility, packages); 71 return api; 72 } 73 finally { 74 removeSources(); 75 } 76 } 77 78 public static void putSource(CompilationUnit source) throws IOException { 79 String directory = sourcepath; 80 String filename = source.getName(); // a.b.C 81 int pos = filename.indexOf("."); 82 while(pos > 0) { 83 directory = directory + filename.substring(0, pos) + separator; 84 filename = filename.substring(pos+1); 85 pos = filename.indexOf("."); 86 } 87 88 File file = new File(directory, filename + ".java"); 89 File parent = file.getParentFile(); 90 parent.mkdirs(); 91 92 FileWriter wr = new FileWriter(file); 93 wr.write(source.getSource()); 94 wr.close(); 95 } 96 97 private static void removeSources() { 98 File file = new File(sourcepath); 99 removeFile(file); 100 } 101 102 private static void removeFile(File file){ 103 if(file.isDirectory()){ 104 for(File f : file.listFiles()) removeFile(f); 105 } 106 file.delete(); 107 } 108 109 private static RootDoc getRootDoc(Visibility visibility, java.util.Set<String> packages) throws IOException { 110 long accessModifier = 0; 111 if(visibility == Visibility.PUBLIC){ 112 accessModifier = 113 com.sun.tools.javac.code.Flags.PUBLIC; // 0x1 114 } 115 if(visibility == Visibility.PROTECTED){ 116 accessModifier = 117 com.sun.tools.javac.code.Flags.PUBLIC // 0x1 118 | com.sun.tools.javac.code.Flags.PROTECTED; // 0x4 119 } 120 if(visibility == Visibility.PACKAGE){ 121 accessModifier = 122 com.sun.tools.javac.code.Flags.PUBLIC // 0x1 123 | com.sun.tools.javac.code.Flags.PROTECTED // 0x4 124 | com.sun.tools.javadoc.ModifierFilter.PACKAGE; // 0x80000000 125 } 126 if(visibility == Visibility.PRIVATE){ 127 accessModifier = 128 com.sun.tools.javac.code.Flags.PUBLIC // 0x1 129 | com.sun.tools.javac.code.Flags.PROTECTED // 0x4 130 | com.sun.tools.javadoc.ModifierFilter.PACKAGE // 0x80000000 131 | com.sun.tools.javac.code.Flags.PRIVATE; // 0x2 132 } 133 134 ModifierFilter showAccess = new ModifierFilter(accessModifier); 135 boolean breakiterator = false; 136 boolean quiet = false; 137 boolean legacy = false; 138 boolean docClasses = false; 139 140 String docLocale = ""; 141 String encoding = null; 142 ListBuffer<String> javaNames = new ListBuffer<String>(); 143 for(String p : packages) 144 javaNames.append(p); 145 146 ListBuffer<String[]> options = new ListBuffer<String[]>(); 147 148 149 // String sourcepath = "//D:/Documents/Projects/08_CTS/signature-tools/signature-tools/test/"; 150 options.append(new String[]{"-sourcepath", sourcepath}); 151 152 ListBuffer<String> subPackages = new ListBuffer<String>(); 153 ListBuffer<String> excludedPackages = new ListBuffer<String>(); 154 155 Context context = new Context(); 156 Options compOpts = Options.instance(context); 157 compOpts.put("-sourcepath", sourcepath); 158 159 Constructor<Messager> c; 160 try { 161 // c = Messager.class.getDeclaredConstructor(Context.class, String.class); 162 // c.setAccessible(true); 163 // c.newInstance(context, "SigTest"); 164 c = Messager.class.getDeclaredConstructor(Context.class, String.class, PrintWriter.class, PrintWriter.class, PrintWriter.class); 165 c.setAccessible(true); 166 PrintWriter err = new PrintWriter(new StringWriter()); 167 PrintWriter warn = new PrintWriter(new StringWriter()); 168 PrintWriter notice = new PrintWriter(new StringWriter()); 169 c.newInstance(context, "SigTest", err, warn, notice); 170 } catch (Exception e) { 171 throw new RuntimeException(e); 172 } 173 174 JavadocTool comp = JavadocTool.make0(context); 175 RootDocImpl root = comp.getRootDocImpl(docLocale, encoding, showAccess, 176 javaNames.toList(), options.toList(), breakiterator, 177 subPackages.toList(), excludedPackages.toList(), docClasses, 178 legacy, quiet); 179 return root; 180 } 181 182 } 183