// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2015 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package com.google.appinventor.components.scripts;
import java.io.IOException;
import java.io.Writer;
import java.util.TreeSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
public final class ComponentTranslationGenerator extends ComponentProcessor {
// Where to write results.
private static final String OUTPUT_FILE_NAME = "ComponentsTranslation.java";
private void outputComponent(ComponentInfo component, StringBuilder sb) {
if (component.getExternal()) { // Avoid adding entries for external components
return;
}
Map<String, Parameter> parameters = new LinkedHashMap<String, Parameter>();
sb.append("\n\n/* Component: " + component.name + " */\n\n");
sb.append(" map.put(\"COMPONENT-" + component.name + "\", MESSAGES." +
Character.toLowerCase(component.name.charAt(0)) + component.name.substring(1) +
"ComponentPallette());\n\n");
sb.append(" map.put(\"" + component.name + "-helpString\", MESSAGES." +
component.name + "HelpStringComponentPallette());\n\n");
sb.append("\n\n/* Properties */\n\n");
for (Property prop : component.properties.values()) {
String propertyName = prop.name;
if (prop.isUserVisible()
|| component.designerProperties.containsKey(propertyName)
|| prop.isDeprecated() // [lyn, 2015/12/30] For deprecated AI2 blocks (but not AI1 blocks)
// must translate property names so they can be displayed in bad blocks.
) {
sb.append(" map.put(\"PROPERTY-" + propertyName + "\", MESSAGES." + propertyName + "Properties());\n");
}
}
sb.append("\n\n/* Events */\n\n");
for (Event event : component.events.values()) {
String propertyName = event.name;
if (event.userVisible
|| event.deprecated // [lyn, 2015/12/30] For deprecated AI2 blocks (but not AI1 blocks)
// must translate property names so they can be displayed in bad blocks.
) {
sb.append(" map.put(\"EVENT-" + propertyName + "\", MESSAGES." + propertyName + "Events());\n");
for (Parameter parameter : event.parameters) {
parameters.put(parameter.name, parameter);
}
}
}
sb.append("\n\n/* Methods */\n\n");
for (Method method : component.methods.values()) {
String propertyName = method.name;
if (method.userVisible
|| method.deprecated // [lyn, 2015/12/30] For deprecated AI2 blocks (but not AI1 blocks)
// must translate property names so they can be displayed in bad blocks.
) {
sb.append(" map.put(\"METHOD-" + propertyName + "\", MESSAGES." + propertyName + "Methods());\n");
for (Parameter parameter : method.parameters) {
parameters.put(parameter.name, parameter);
}
}
}
sb.append("\n\n/* Parameters */\n\n");
for (Parameter parameter : parameters.values()) {
sb.append(" map.put(\"PARAM-" + parameter.name + "\", MESSAGES." +
Character.toLowerCase(parameter.name.charAt(0)) + parameter.name.substring(1) +
"Params());\n");
}
}
private void outputCategory(String category, StringBuilder sb) {
// santize the category name
String[] parts = category.split(" ");
sb.append(" map.put(\"CATEGORY-" + category + "\", MESSAGES." + parts[0].replaceAll("[^A-Za-z0-9]", "").toLowerCase());
for (int i = 1; i < parts.length; i++) {
String lower = parts[i].replaceAll("[^A-Za-z0-9]", "").toLowerCase();
sb.append(Character.toUpperCase(lower.charAt(0)));
sb.append(lower.substring(1));
}
sb.append("ComponentPallette());\n");
}
@Override
protected void outputResults() throws IOException {
StringBuilder sb = new StringBuilder();
sb.append("package com.google.appinventor.client;\n");
sb.append("");
sb.append("import java.util.HashMap;\n");
sb.append("import java.util.Map;\n");
sb.append("");
sb.append("import static com.google.appinventor.client.Ode.MESSAGES;\n");
sb.append("");
sb.append("public class ComponentsTranslation {\n");
sb.append(" public static Map<String, String> myMap = map();\n\n");
sb.append(" private static String getName(String key) {\n");
sb.append(" String value = myMap.get(key);\n");
sb.append(" if (key == null) {\n");
sb.append(" return \"**Missing key in ComponentsTranslations**\";\n");
sb.append(" } else {\n");
sb.append(" return value;\n");
sb.append(" }\n");
sb.append(" }\n\n");
sb.append(" public static String getPropertyName(String key) {\n");
sb.append(" String value = getName(\"PROPERTY-\" + key);\n");
sb.append(" if(value == null) return key;\n");
sb.append(" return value;\n");
sb.append(" }\n");
sb.append("\n");
sb.append(" public static String getMethodName(String key) {\n");
sb.append(" String value = getName(\"METHOD-\" + key);\n");
sb.append(" if(value == null) return key;\n");
sb.append(" return value;\n");
sb.append(" }\n");
sb.append("\n");
sb.append(" public static String getEventName(String key) {\n");
sb.append(" String value = getName(\"EVENT-\" + key);\n");
sb.append(" if(value == null) return key;\n");
sb.append(" return value;\n");
sb.append(" }\n");
sb.append("\n");
sb.append(" public static String getComponentName(String key) {\n");
sb.append(" String value = getName(\"COMPONENT-\" + key);\n");
sb.append(" if(value == null) return key;\n");
sb.append(" return value;\n");
sb.append(" }\n");
sb.append("\n");
sb.append(" public static String getCategoryName(String key) {\n");
sb.append(" String value = getName(\"CATEGORY-\" + key);\n");
sb.append(" if(value == null) return key;\n");
sb.append(" return value;\n");
sb.append(" }\n");
sb.append("\n");
sb.append(" public static String getComponentHelpString(String key) {\n");
sb.append(" String value = getName(key + \"-helpString\");\n");
sb.append(" if(value == null) return key;\n");
sb.append(" return value;\n");
sb.append(" }\n");
sb.append(" public static HashMap<String, String> map() {\n");
sb.append(" HashMap<String, String> map = new HashMap<String, String>();\n");
// Components are already sorted.
Set<String> categories = new TreeSet<String>();
for (Map.Entry<String, ComponentInfo> entry : components.entrySet()) {
ComponentInfo component = entry.getValue();
outputComponent(component, sb);
categories.add(component.getCategory());
}
sb.append("\n\n /* Categories */\n\n");
for (String category : categories) {
outputCategory(category, sb);
}
sb.append(" return map;\n");
sb.append(" }\n");
sb.append("}\n");
FileObject src = createOutputFileObject(OUTPUT_FILE_NAME);
Writer writer = src.openWriter();
writer.write(sb.toString());
writer.flush();
writer.close();
messager.printMessage(Diagnostic.Kind.NOTE, "Wrote file " + src.toUri());
}
}