AI2 Component  (Version nb184)
DocumentationGenerator.java
Go to the documentation of this file.
1 // -*- mode: java; c-basic-offset: 2; -*-
2 // Copyright 2009-2011 Google, All Rights reserved
3 // Copyright 2011-2012 MIT, All rights reserved
4 // Released under the Apache License, Version 2.0
5 // http://www.apache.org/licenses/LICENSE-2.0
6 
7 package com.google.appinventor.components.scripts;
8 
10 
11 import javax.tools.Diagnostic;
12 import javax.tools.FileObject;
13 import java.io.IOException;
14 import java.io.Writer;
15 import java.util.Map;
16 
29  private static final String OUTPUT_FILE_NAME = "component-doc.html";
30 
34  private String getComponentOutputString(String componentName, String componentDescription) {
35  return String.format("\n<h2 id=\"%1$s\">%1$s</h2>\n\n" +
36  "<p>%2$s</p>\n\n",
37  componentName, componentDescription);
38  }
39 
43  private String getPropertyDefinition(String name, String description,
44  boolean isUserVisible, boolean isReadable, boolean isWritable) {
45 
46  if (!isUserVisible) {
47  return String.format(" <dt><code>%s</code> (designer only)</dt>\n <dd>%s</dd>\n",
48  name, description);
49  }
50  else if (isReadable && !isWritable) {
51  return String.format(" <dt><code><em>%s</em></code></dt>\n <dd>%s</dd>\n",
52  name, description);
53  }
54  return String.format(" <dt><code>%s</code></dt>\n <dd>%s</dd>\n",
55  name, description);
56  }
57 
61  private String getEventDefinition(String name, String parameters, String description) {
62  return String.format(" <dt><code>%s(%s)</code></dt>\n <dd>%s</dd>\n",
63  name, parameters, description);
64  }
65 
70  private String getMethodDefinition(String name, String parameters, String returnType,
71  String description) {
72  return String.format(" <dt><code>%s%s%s(%s)</code></dt>\n <dd>%s</dd>\n",
73  returnType, returnType.isEmpty() ? "" : " ",
74  name, parameters, description);
75  }
76 
77  protected final void outputResults() throws IOException {
78  // Begin writing output file.
79  FileObject src = createOutputFileObject(OUTPUT_FILE_NAME);
80  Writer writer = src.openWriter();
81 
82  // Output table at top showing components by category.
83  outputCategories(writer);
84 
85  // Components are already sorted.
86  for (Map.Entry<String, ComponentInfo> entry : components.entrySet()) {
87  ComponentInfo component = entry.getValue();
88  outputComponent(writer, component);
89  }
90 
91  // Close output file
92  writer.flush();
93  writer.close();
94  messager.printMessage(Diagnostic.Kind.NOTE, "Wrote file " + src.toUri());
95  }
96 
104  private void outputComponent(Writer writer, ComponentInfo component) throws IOException {
105  // Output component name and description.
106  writer.write(getComponentOutputString(component.name,
107  component.description));
108 
109  // Output properties, events, and methods.
110  outputProperties(writer, component);
111  outputEvents(writer, component);
112  outputMethods(writer, component);
113  }
114 
115  // Output table showing categories (e.g., "Sensors") and components in them.
116  // This hardcodes a two-column table as output with certain categories in the
117  // left column and certain other categories in the right column.
118  private void outputCategories(Writer writer)
119  throws java.io.IOException {
120  // Output table header
121  writer.write("<table style=\"border-color: rgb(136, 136, 136); border-width: 0px; " +
122  "border-collapse: collapse;\" border=\"0\" bordercolor=\"#888888\" " +
123  "cellpadding=\"5\" cellspacing=\"5\">\n");
124  writer.write("<tbody valign=\"top\">\n");
125  writer.write("<tr>\n");
126 
127  // Specify which categories are in which output column.
128  final ComponentCategory[][] categories = {
129  // Column one categories
130  {
131  ComponentCategory.USERINTERFACE,
132  ComponentCategory.LAYOUT,
133  ComponentCategory.MEDIA,
134  ComponentCategory.ANIMATION,
135  ComponentCategory.SOCIAL
136  },
137  // Column two categories
138  {
139  ComponentCategory.STORAGE,
140  ComponentCategory.CONNECTIVITY,
141  ComponentCategory.SENSORS,
142  ComponentCategory.LEGOMINDSTORMS,
143  //ComponentCategory.EXPERIMENTAL
144  }
145  };
146 
147  // Output the body of the table.
148  for (int column = 0; column < java.lang.reflect.Array.getLength(categories); column++) {
149  writer.write("<td>");
150  for (int row = 0; row < java.lang.reflect.Array.getLength(categories[column]); row++) {
151  // Output the category header.
152  String categoryName = categories[column][row].getName();
153  writer.write(String.format("<b><font size=\"5\">%s</font></b>\n<ul>\n",
154  categoryName.replace("\u00AE", "&copy;")));
155  // Output the components with this category. This algorithm for getting
156  // components by category has poor complexity performance but is probably
157  // more efficient in practice than maintaining a hash table mapping
158  // categories to components.
159  for (Map.Entry<String, ComponentInfo> entry : components.entrySet()) {
160  ComponentInfo component = entry.getValue();
161  if (categoryName.equals(component.getCategory())) {
162  writer.write(String.format(" <li><a href=\"#%1$s\">%1$s</a></li>\n",
163  component.name));
164  }
165  }
166  writer.write("</ul>\n");
167  }
168  writer.write("</td>\n");
169  // For aesthetic purposes, output empty column between category columns.
170  writer.write("<td style=\"width: 60px;\"><b><font size=\"5\"><br/></font></b></td>");
171  }
172 
173  // Write table footer
174  writer.write("</tr>\n</tbody>\n</table>\n");
175  }
176 
177  private void outputProperties(Writer writer, ComponentInfo component)
178  throws java.io.IOException {
179  writer.write("<h3>Properties</h3>\n");
180  // Only list properties that are user-visible or designer properties.
181  boolean definitionWritten = false;
182  for (Map.Entry<String, Property> entry : component.properties.entrySet()) {
183  Property property = entry.getValue();
184  if (property.isDeprecated()) continue;
185  if (property.isUserVisible() || component.designerProperties.containsKey(property.name)) {
186  if (!definitionWritten) {
187  writer.write("<dl>\n");
188  }
189  writer.write(getPropertyDefinition(property.name,
190  property.getDescription(),
191  property.isUserVisible(),
192  property.isReadable(),
193  property.isWritable()));
194  definitionWritten = true;
195  }
196  }
197  if (definitionWritten) {
198  writer.write("</dl>\n\n");
199  } else {
200  writer.write("none\n\n");
201  }
202  }
203 
204  private void outputEvents(Writer writer, ComponentInfo component) throws java.io.IOException {
205  writer.write("<h3>Events</h3>\n");
206  // Only list events that are user-visible.
207  boolean definitionWritten = false;
208  for (Map.Entry<String, Event> entry : component.events.entrySet()) {
209  Event event = entry.getValue();
210  if (event.deprecated) continue;
211  if (event.userVisible) {
212  if (!definitionWritten) {
213  writer.write("<dl>\n");
214  }
215  writer.write(getEventDefinition(event.name, event.toParameterString(), event.description));
216  definitionWritten = true;
217  }
218  }
219  if (definitionWritten) {
220  writer.write("</dl>\n\n");
221  } else {
222  writer.write("none\n\n");
223  }
224  }
225 
226  private void outputMethods(Writer writer, ComponentInfo component) throws java.io.IOException {
227  writer.write("<h3>Methods</h3>\n");
228  // Only list methods that are user-visible.
229  boolean definitionWritten = false;
230  for (Map.Entry<String, Method> entry : component.methods.entrySet()) {
231  Method method = entry.getValue();
232  if (method.deprecated) continue;
233  if (method.userVisible) {
234  if (!definitionWritten) {
235  writer.write("<dl>\n");
236  }
237  String returnType = method.getReturnType();
238  writer.write(getMethodDefinition(
239  method.name, method.toParameterString(),
240  returnType == null ? "" : javaTypeToYailType(returnType),
241  method.description));
242  definitionWritten = true;
243  }
244  }
245  if (definitionWritten) {
246  writer.write("</dl>\n\n");
247  } else {
248  writer.write("none\n\n");
249  }
250  }
251 }
com.google.appinventor.components
com.google.appinventor.components.scripts.DocumentationGenerator
Definition: DocumentationGenerator.java:28
com.google.appinventor.components.scripts.ComponentProcessor.messager
Messager messager
Definition: ComponentProcessor.java:194
com.google.appinventor.components.scripts.DocumentationGenerator.outputResults
final void outputResults()
Definition: DocumentationGenerator.java:77
com.google.appinventor.components.scripts.ComponentProcessor.ComponentInfo
Definition: ComponentProcessor.java:644
com.google.appinventor.components.common
Definition: ComponentCategory.java:7
com.google.appinventor.components.common.ComponentCategory
Definition: ComponentCategory.java:48
com.google.appinventor.components.scripts.ComponentProcessor.components
final SortedMap< String, ComponentInfo > components
Definition: ComponentProcessor.java:207
com.google
com
com.google.appinventor.components.scripts.ComponentProcessor
Definition: ComponentProcessor.java:124
com.google.appinventor