package org.openprovenance.prov.template; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.HashSet; import java.util.Set; import javax.lang.model.element.Modifier; import org.openprovenance.prov.model.Document; import org.openprovenance.prov.model.Bundle; import org.openprovenance.prov.model.ProvFactory; import org.openprovenance.prov.model.ProvUtilities; import org.openprovenance.prov.model.QualifiedName; import org.openprovenance.prov.model.Statement; import com.google.common.base.CaseFormat; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.TypeSpec; import com.squareup.javapoet.TypeSpec.Builder; public class BindingsBeanGenerator { final private ProvFactory pFactory; public BindingsBeanGenerator(ProvFactory pFactory) { this.pFactory=pFactory; } static ProvUtilities u= new ProvUtilities(); public boolean generate(Document doc, String templateName, String packge, String location, String resource) { try { String bn=beanName(templateName); String destinationDir=location + "/" + packge.replace('.', '/') + "/"; String destination=destinationDir + bn + ".java"; JavaFile spec=generateSpecification(doc,bn,templateName,packge, resource); PrintWriter out; try { File dir=new File(destinationDir); if (!dir.exists() && !dir.mkdirs()) { System.err.println("failed to create directory " + destinationDir); return false; }; out = new PrintWriter(destination); out.print(spec); out.close(); return true; } catch (FileNotFoundException e) { e.printStackTrace(); return false; } } catch (Exception e) { e.printStackTrace(); return false; } } public String beanName(String templateName) { return capitalize(templateName)+"BindingsBean"; } public String capitalize(String templateName) { return templateName.substring(0, 1).toUpperCase()+templateName.substring(1); } public JavaFile generateSpecification(Document doc, String name, String templateName, String packge, String resource) { Bundle bun=u.getBundle(doc).get(0); Set<QualifiedName> allVars=new HashSet<QualifiedName>(); Set<QualifiedName> allAtts=new HashSet<QualifiedName>(); for (Statement statement: bun.getStatement()) { Set<QualifiedName> vars=ExpandUtil.freeVariables(statement); allVars.addAll(vars); Set<QualifiedName> vars2=ExpandUtil.freeAttributeVariables(statement, pFactory); allAtts.addAll(vars2); } return generate(allVars,allAtts,name, templateName, packge, resource); } public JavaFile generate(Set<QualifiedName> allVars, Set<QualifiedName> allAtts, String name, String templateName, String packge, String resource) { Builder builder = generateClassBuilder(name); builder.addMethod(generateConstructor()); for (QualifiedName q: allVars) { builder.addMethod(generateVarMutator(q)); } for (QualifiedName q: allAtts) { builder.addMethod(generateAttMutator(q,QualifiedName.class)); builder.addMethod(generateAttMutator(q,String.class)); } builder.addMethod(generateBindingsGetter()); builder.addMethod(generateTemplateResourceGetter(resource)); TypeSpec bean=builder.build(); JavaFile myfile = JavaFile.builder(packge, bean) .addFileComment("Generated Automatically by ProvToolbox for template $S",templateName) .build(); return myfile; } public Builder generateClassBuilder(String name) { return TypeSpec.classBuilder(name) .addModifiers(Modifier.PUBLIC) .addSuperinterface(BindingsBean.class) .addField(Bindings.class, "bindings", Modifier.PRIVATE, Modifier.FINAL) .addField(ProvFactory.class, "pf", Modifier.PRIVATE, Modifier.FINAL); } public MethodSpec generateConstructor() { return MethodSpec.constructorBuilder() .addModifiers(Modifier.PUBLIC) .addParameter(ProvFactory.class, "pf") .addStatement("this.$N = $N", "pf", "pf") .addStatement("this.bindings = new $T($N)", Bindings.class, "pf") .build(); } public String camelcase(String s) { return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, s); } public MethodSpec generateVarMutator(QualifiedName v) { final String local=v.getLocalPart(); final String localCamel= camelcase(local); MethodSpec method = MethodSpec.methodBuilder("add" + localCamel) .addModifiers(Modifier.PUBLIC) .returns(void.class) .addParameter(QualifiedName.class, "arg") .addStatement("bindings.addVariable($S,arg)",local) .build(); return method; } public MethodSpec generateAttMutator(QualifiedName v, Class typ) { final String local=v.getLocalPart(); final String localCamel= camelcase(local); MethodSpec method = MethodSpec.methodBuilder("add" + localCamel) .addModifiers(Modifier.PUBLIC) .returns(void.class) .addParameter(typ, "arg") .addStatement("bindings.addAttribute($S,arg)",local) .build(); return method; } public MethodSpec generateBindingsGetter() { MethodSpec method = MethodSpec.methodBuilder("getBindings") .addModifiers(Modifier.PUBLIC) .returns(Bindings.class) .addStatement("return bindings") .build(); return method; } public MethodSpec generateTemplateResourceGetter(String resource) { MethodSpec method = MethodSpec.methodBuilder("getTemplate") .addModifiers(Modifier.PUBLIC) .returns(String.class) .addStatement("return $S",resource) .build(); return method; } }