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 
convert(Visibility visibility, Set<CompilationUnit> units)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 
putSource(CompilationUnit source)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 
removeSources()97     private static void removeSources() {
98         File file = new File(sourcepath);
99         removeFile(file);
100     }
101 
removeFile(File file)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 
getRootDoc(Visibility visibility, java.util.Set<String> packages)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