1 package no.sesat.mojo.modes;
2
3 import static com.sun.tools.javac.code.Flags.PROTECTED;
4 import static com.sun.tools.javac.code.Flags.PUBLIC;
5
6 import java.io.ByteArrayOutputStream;
7 import java.io.File;
8 import java.io.IOException;
9 import java.io.PrintStream;
10 import java.util.Vector;
11
12 import com.sun.javadoc.ClassDoc;
13 import com.sun.javadoc.RootDoc;
14 import com.sun.tools.javac.util.Context;
15 import com.sun.tools.javac.util.ListBuffer;
16 import com.sun.tools.javac.util.Options;
17 import com.sun.tools.javadoc.JavadocTool;
18 import com.sun.tools.javadoc.Messager;
19 import com.sun.tools.javadoc.ModifierFilter;
20 import com.sun.tools.javadoc.RootDocImpl;
21
22
23
24
25
26 public final class Builder {
27
28 private static String outputDir = "";
29 private static String id = "";
30
31 private Builder() {
32 }
33
34
35
36
37
38
39
40
41
42
43
44 public static void build(final String classpath, final String dir, final String idString) {
45 outputDir = new File(dir).getAbsolutePath() + File.separator;
46 id = idString;
47 RootDocImpl root = null;
48
49
50 final PrintStream out = System.out;
51 final PrintStream err = System.err;
52 try {
53 System.setOut(new PrintStream(new ByteArrayOutputStream()));
54 System.setErr(new PrintStream(new ByteArrayOutputStream()));
55
56 final Context context = new Context();
57 Messager.preRegister(context, "Builder");
58 final JavadocTool comp = JavadocTool.make0(context);
59
60 final ListBuffer<String> subPackages = new ListBuffer<String>();
61 subPackages.append("no");
62 final ListBuffer<String> xcludePackages = new ListBuffer<String>();
63 final ListBuffer<String> javaNames = new ListBuffer<String>();
64 final ListBuffer<String[]> options = new ListBuffer<String[]>();
65
66 final Options compOpts = Options.instance(context);
67 compOpts.put("-classpath", classpath);
68
69 try {
70 root = comp.getRootDocImpl("", "", new ModifierFilter(PUBLIC | PROTECTED), javaNames.toList(), options
71 .toList(), false, subPackages.toList(), xcludePackages.toList(), false, false, false);
72 } catch (IOException e) {
73 e.printStackTrace(err);
74 return;
75 }
76 } catch (Throwable e) {
77
78 out.print("Generating schema files failed due to error: " + e.getMessage());
79 } finally {
80 System.setOut(out);
81 System.setErr(err);
82 }
83 if (root != null) {
84 start(root);
85 }
86 }
87
88
89
90
91
92
93
94
95 public static boolean start(final RootDoc root) {
96 final ConfigElement defaultConvert = new ConfigElement("default-convert");
97 defaultConvert.attributes.add(new ConfigAttribute("name"));
98 defaultConvert.attributes.add(new ConfigAttribute("prefix"));
99 defaultConvert.attributes.add(new ConfigAttribute("postfix"));
100
101 final Vector<ConfigElement> commands = new Vector<ConfigElement>();
102 final Vector<ConfigElement> resultHandlers = new Vector<ConfigElement>();
103 final Vector<ConfigElement> queryTransformers = new Vector<ConfigElement>();
104 {
105 final ClassDoc[] classes = root.classes();
106 for (int i = 0; i < classes.length; i++) {
107 final String name = classes[i].name();
108 if (name.endsWith("Config") && !classes[i].isAbstract()) {
109 final ConfigElement element = new ConfigElement(classes[i]);
110
111 if (name.endsWith("CommandConfig")) {
112 element.applyNameFilter(new NameFilter() {
113 public String filter(final String name) {
114 return toXmlName(name.substring(0, name.lastIndexOf("Config")));
115 }
116 });
117 commands.add(element);
118 } else if (name.endsWith("ResultHandlerConfig")) {
119 element.applyNameFilter(new NameFilter() {
120 public String filter(final String name) {
121 return toXmlName(name.substring(0, name.lastIndexOf("ResultHandlerConfig")));
122 }
123 });
124 if (!element.name.isEmpty()) {
125 resultHandlers.add(element);
126 }
127 } else if (name.endsWith("QueryTransformer") || (name.endsWith("QueryTransformerConfig"))) {
128 element.applyNameFilter(new NameFilter() {
129 public String filter(final String name) {
130 return toXmlName(name.substring(0, name.lastIndexOf("QueryTransformer")));
131 }
132 });
133
134 if (name.equals("NewsCaseQueryTransformerConfig")) {
135 element.addChild(defaultConvert);
136 }
137
138 queryTransformers.add(element);
139 } else {
140 System.out.println("Lost: " + element.name);
141 }
142 }
143 }
144 }
145
146 final ConfigElement modes = new ConfigElement("modes");
147 modes.attributes.add(new ConfigAttribute("template-prefix"));
148
149 final ConfigElement mode = new ConfigElement("mode");
150 mode.attributes.add(new ConfigAttribute("id"));
151 mode.attributes.add(new ConfigAttribute("inherit"));
152 mode.attributes.add(new ConfigAttribute("analysis"));
153 mode.attributes.add(new ConfigAttribute("executor"));
154
155 mode.addChildren(commands);
156 modes.addChild(mode);
157
158 final ConfigElement resultHandler = new ConfigElement("result-handlers");
159 resultHandler.addChildren(resultHandlers);
160
161 final ConfigElement queryTransform = new ConfigElement("query-transformers");
162 queryTransform.addChildren(queryTransformers);
163
164 final ConfigElement navigators = new ConfigElement("navigators");
165 final ConfigElement navigator = new ConfigElement("navigator");
166 navigator.attributes.add(new ConfigAttribute("id", null, true));
167 navigator.attributes.add(new ConfigAttribute("name", null, true));
168 navigator.attributes.add(new ConfigAttribute("field", null, true));
169 navigator.attributes.add(new ConfigAttribute("display-name", null, true));
170 navigator.attributes.add(new ConfigAttribute("sort", null, false));
171 navigator.attributes.add(new ConfigAttribute("boundary-match"));
172
173
174 navigator.addChild(navigator);
175
176
177 navigators.addChild(navigator);
178
179 for (ConfigElement command : commands) {
180 command.addChild(resultHandler);
181 command.addChild(queryTransform);
182 command.addChild(navigators);
183 }
184
185 final Runnable[] jobs = {new GenerateRelaxNG(modes, outputDir + "modes.rnc", id),
186 new GenerateXSD(modes, outputDir + "modes.xsd", id),
187 new GenerateDTD(modes, outputDir + "modes.dtd", id)};
188 final int jobCount = 5;
189 for (int i = 0; i < (jobs.length + jobCount - 1); i++) {
190
191 if (i < jobs.length) {
192
193 final Thread thread = new Thread(jobs[i]);
194 thread.start();
195 jobs[i] = thread;
196 }
197 if (i >= (jobCount - 1)) {
198 try {
199 ((Thread) jobs[i - jobCount + 1]).join();
200
201 } catch (InterruptedException e) {
202 e.printStackTrace();
203 }
204 }
205 }
206
207 System.out.println("commands : " + commands.size());
208 System.out.println("result handlers : " + resultHandlers.size());
209 System.out.println("query transformers : " + queryTransformers.size());
210
211 return true;
212 }
213
214
215
216
217
218
219
220
221 public static String toXmlName(final String name) {
222 final StringBuilder xmlName = new StringBuilder(name);
223 for (int i = 0; i < xmlName.length(); ++i) {
224 final char c = xmlName.charAt(i);
225 if (Character.isUpperCase(c)) {
226 xmlName.replace(i, i + 1, (i == 0 ? "" : "-") + Character.toLowerCase(c));
227 ++i;
228 }
229 }
230 return xmlName.toString();
231 }
232 }