/*
* Copyright 2015 Workday, Inc.
*
* This software is available under the MIT license.
* Please see the LICENSE.txt file in this project.
*/
package com.workday.autoparse.xml.codegen;
import com.squareup.javawriter.JavaWriter;
import com.workday.autoparse.xml.context.XmlParserSettingsBuilder;
import com.workday.autoparse.xml.parser.GeneratedClassNames;
import com.workday.autoparse.xml.parser.ParserMap;
import com.workday.autoparse.xml.parser.XmlElementParser;
import com.workday.meta.Modifiers;
import java.io.IOException;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.tools.JavaFileObject;
/**
* @author nathan.taylor
* @since 2013-9-17
*/
class ParserMapGenerator {
private static final String MAP_TYPE =
String.format("Map<String, %s<?>>", XmlElementParser.class.getSimpleName());
private final ProcessingEnvironment processingEnv;
private final PackageElement packageElement;
private final Map<String, TypeElement> parseMap;
ParserMapGenerator(ProcessingEnvironment processingEnv, PackageElement packageElement,
Map<String, TypeElement> parseMap) {
this.processingEnv = processingEnv;
this.packageElement = packageElement;
this.parseMap = parseMap;
}
public void generateParseMap() throws IOException {
String packageName = packageElement != null
? packageElement.getQualifiedName().toString()
: XmlParserSettingsBuilder.DEFAULT_PACKAGE;
String parserMapClassName = GeneratedClassNames.CLASS_GENERATED_PARSER_MAP;
String qualifiedClassName = GeneratedClassNames.getQualifiedName(packageName,
parserMapClassName);
JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(qualifiedClassName);
JavaWriter writer = new JavaWriter(sourceFile.openWriter());
writer.emitPackage(packageName);
writer.emitImports(getParsableClassImports());
writer.emitEmptyLine();
writer.emitImports(getJavaImports());
writer.emitEmptyLine();
writer.beginType(GeneratedClassNames.CLASS_GENERATED_PARSER_MAP,
"class",
EnumSet.of(Modifier.PUBLIC, Modifier.FINAL),
null,
ParserMap.class.getCanonicalName());
writer.emitEmptyLine();
writeMapField(writer);
writer.emitEmptyLine();
writeGetter(writer);
writer.emitEmptyLine();
writeKeySet(writer);
writer.endType();
writer.close();
}
private Set<String> getParsableClassImports() {
Set<String> results = new HashSet<>();
for (TypeElement element : parseMap.values()) {
results.add(element.getQualifiedName().toString() + GeneratedClassNames.PARSER_SUFFIX);
}
return results;
}
private Set<String> getJavaImports() {
Set<String> results = new HashSet<>();
results.add(Map.class.getCanonicalName());
results.add(HashMap.class.getCanonicalName());
if (packageElement != null) {
results.add(ParserMap.class.getCanonicalName());
results.add(XmlElementParser.class.getCanonicalName());
}
return results;
}
private void writeMapField(JavaWriter writer) throws IOException {
writer.emitField(MAP_TYPE, "MAP", Modifiers.PRIVATE_CONSTANT,
String.format("new HashMap<String, %s<?>>()",
XmlElementParser.class.getSimpleName()));
writer.beginInitializer(true);
for (Map.Entry<String, TypeElement> entry : parseMap.entrySet()) {
writer.emitStatement("MAP.put(\"%s\", %s.INSTANCE)", entry.getKey(),
entry.getValue().getSimpleName()
+ GeneratedClassNames.PARSER_SUFFIX);
}
writer.endInitializer();
}
private void writeGetter(JavaWriter writer) throws IOException {
writer.emitAnnotation(Override.class);
writer.beginMethod(JavaWriter.type(XmlElementParser.class, "?"),
"get",
EnumSet.of(Modifier.PUBLIC),
"String",
"name");
writer.emitStatement("return MAP.get(name)");
writer.endMethod();
}
private void writeKeySet(JavaWriter writer) throws IOException {
writer.emitAnnotation(Override.class);
writer.beginMethod(JavaWriter.type(Set.class, "String"), "keySet", Modifiers.PUBLIC);
writer.emitStatement("return MAP.keySet()");
writer.endMethod();
}
}