package pt.ist.fenixframework.dml; import java.io.*; import java.net.*; import java.util.Iterator; import pt.ist.dap.implementation.DAPConfig; import pt.ist.fenixframework.FenixFramework; /** * This code generator adds the possibility of collecting information about the data access * patterns performed by any target application built with the fenix-framework. To do so, it adds, * at the start of each setter and getter method an invocation to a static method in the DAP framework * that updates the statistical information regarding that particular read/write access operation. * @author syg * @see pt.ist.fenixframework.dap.FFDAPConfig */ public class DAPCodeGenerator extends DefaultCodeGenerator { public static final String DAP_ON_CONFIG_KEY = "ptIstDapEnable"; public static final String DAP_ON_CONFIG_VALUE = "true"; private final boolean DAP_ENABLED; protected static DomainClass dC = null; public DAPCodeGenerator(CompilerArgs compArgs, DomainModel domainModel) { super(compArgs, domainModel); //System.out.println("\n\n__DAPCodeGenerator__\n\n"); String state = compArgs.getParams().get(DAP_ON_CONFIG_KEY); DAP_ENABLED = (state != null) && state.trim().equalsIgnoreCase(DAP_ON_CONFIG_VALUE); } public final String getGetterDAPStatement(DomainClass domainClass, String slotName, String typeName) { //System.out.println("\tGenerating getter DAP statement for " + domainClass.getFullName() + "." + slotName + " of type " + typeName); if (DAP_ENABLED) return "pt.ist.dap.implementation.simple.SimpleContextManager.updateReadStatisticsWithoutContext(\"" + domainClass.getFullName() + "\", \"" + slotName + "\");"; else return ""; } public final String getSetterDAPStatement(DomainClass domainClass, String slotName, String typeName) { //System.out.println("\tGenerating setter DAP statement for " + domainClass.getFullName() + "." + slotName + " of type " + typeName); if (DAP_ENABLED) return "pt.ist.dap.implementation.simple.SimpleContextManager.updateWriteStatisticsWithoutContext(\"" + domainClass.getFullName() + "\", \"" + slotName + "\");"; else return ""; } protected final void generateGetterDAPStatement(DomainClass domainClass, String slotName, String typeName, PrintWriter out) { if (DAP_ENABLED) println(out, getGetterDAPStatement(domainClass, slotName, typeName)); } protected final void generateSetterDAPStatement(DomainClass domainClass, String slotName, String typeName, PrintWriter out) { if (DAP_ENABLED) println(out, getSetterDAPStatement(domainClass, slotName, typeName)); } @Override protected void generateClasses(Iterator classesIter) { //System.out.println("DAPCodeGenerator::generateClasses"); while (classesIter.hasNext()) { dC = (DomainClass) classesIter.next(); //System.out.println("\nGenerating domainClass " + dC.getFullName()); generateOneClass(dC); } } @Override protected void generateGetterBody(String slotName, String typeName, PrintWriter out) { //System.out.println("\tGenerating getter body for " + slotName + " of type " + typeName); generateGetterDAPStatement(dC, slotName, typeName, out); //if (DAP_ENABLED) { //print(out, "pt.ist.dap.implementation.simple.SimpleContextManager.updateReadStatisticsWithoutContext(\""+ dC.getFullName() +"\", \""); //print(out, slotName); //println(out, "\");"); //} super.generateGetterBody(slotName, typeName, out); } @Override protected void generateSetterBody(DomainClass domainClass, String setterName, Slot slot, PrintWriter out) { //System.out.println("\tGenerating setter body named " + setterName + "() for slot " + slot.getName() + " of type " + slot.getTypeName()); generateSetterDAPStatement(domainClass, slot.getName(), slot.getTypeName(), out); //if (DAP_ENABLED) { //generateSetterDAPStatement(domainClass, slot.getName(), slot.getTypeName(), out); //print(out, "pt.ist.dap.implementation.simple.SimpleContextManager.updateWriteStatisticsWithoutContext(\""+ domainClass.getFullName() +"\", \""); //print(out, slot.getName()); //println(out, "\");"); //} super.generateSetterBody(domainClass, setterName, slot, out); } //N.B: the only difference between this method and the one in the super CodeGenerator is the single invocation to the DAP framework @Override protected void generateRoleSlotMethodsMultOneHas(Role role, PrintWriter out) { String slotName = role.getName(); String capitalizedSlotName = capitalize(slotName); String getterName = "get" + capitalizedSlotName; String methodModifiers = getMethodModifiers(); newline(out); printMethod(out, methodModifiers, "boolean", "has" + capitalizedSlotName); startMethodBody(out); generateGetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out); print(out, "return ("); print(out, getterName); print(out, "() != null);"); endMethodBody(out); } //N.B: the only difference between this method and the one in the super CodeGenerator is the single invocation to the DAP framework @Override protected void generateRoleSlotMethodsMultOneRemove(Role role, PrintWriter out) { String slotName = role.getName(); String capitalizedSlotName = capitalize(slotName); String setterName = "set" + capitalizedSlotName; String methodModifiers = getMethodModifiers(); newline(out); printMethod(out, methodModifiers, "void", "remove" + capitalizedSlotName); startMethodBody(out); generateSetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out); print(out, setterName); print(out, "(null);"); endMethodBody(out); } //N.B: the only difference between this method and the one in the super CodeGenerator is the single invocation to the DAP framework @Override protected void generateRoleSlotMethodsMultStarCount(Role role, PrintWriter out, String methodModifiers, String capitalizedSlotName, String slotAccessExpression) { newline(out); printMethod(out, methodModifiers, "int", "get" + capitalizedSlotName + "Count"); startMethodBody(out); generateGetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out); print(out, "return "); print(out, slotAccessExpression); print(out, ".size();"); endMethodBody(out); } //N.B: the only difference between this method and the one in the super CodeGenerator is the single invocation to the DAP framework @Override protected void generateRoleSlotMethodsMultStarHasAnyChild(Role role, PrintWriter out, String methodModifiers, String capitalizedSlotName, String slotAccessExpression) { newline(out); printMethod(out, methodModifiers, "boolean", "hasAny" + capitalizedSlotName); startMethodBody(out); generateGetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out); print(out, "return (! "); print(out, slotAccessExpression); print(out, ".isEmpty());"); endMethodBody(out); } //N.B: the only difference between this method and the one in the super CodeGenerator is the single invocation to the DAP framework @Override protected void generateRoleSlotMethodsMultStarHasChild(Role role, PrintWriter out, String methodModifiers, String capitalizedSlotName, String slotAccessExpression, String typeName, String slotName, boolean isIndexed, String indexGetterCall) { newline(out); printMethod(out, methodModifiers, "boolean", "has" + capitalizedSlotName, makeArg(typeName, slotName)); startMethodBody(out); generateGetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out); print(out, "return "); print(out, slotAccessExpression); print(out, "."); print(out, (isIndexed ? "containsKey(" : "contains(")); print(out, slotName); if (isIndexed) { print(out, "."); print(out, indexGetterCall); } print(out, ");"); endMethodBody(out); } //N.B: the only difference between this method and the one in the super CodeGenerator is the single invocation to the DAP framework @Override protected void generateRoleSlotMethodsMultStarSet(Role role, PrintWriter out, String methodModifiers, String capitalizedSlotName, String slotAccessExpression, String slotName, String typeName) { newline(out); printMethod(out, methodModifiers, makeGenericType("java.util.Set", typeName), "get" + capitalizedSlotName + "Set"); startMethodBody(out); generateGetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out); print(out, "return "); print(out, slotAccessExpression); print(out, ";"); endMethodBody(out); } //N.B: the only difference between this method and the one in the super CodeGenerator is the single invocation to the DAP framework @Override protected void generateRelationGetter(String getterName, String valueToReturn, Role role, String typeName, PrintWriter out) { newline(out); printFinalMethod(out, "public", typeName, getterName); startMethodBody(out); generateGetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out); print(out, "return "); print(out, "new "); print(out, getRelationAwareTypeFor(role)); print(out, "(("); print(out, getTypeFullName(role.getOtherRole().getType())); print(out, ")this, "); print(out, getRelationSlotNameFor(role)); print(out, ", "); print(out, role.getName()); print(out, ")"); print(out, ";"); endMethodBody(out); } //N.B: the only difference between this method and the one in the super CodeGenerator is the single invocation to the DAP framework protected void generateIteratorMethod(Role role, PrintWriter out, final String slotAccessExpression) { newline(out); printFinalMethod(out, "public", makeGenericType("java.util.Iterator", getTypeFullName(role.getType())), "get" + capitalize(role.getName()) + "Iterator"); startMethodBody(out); generateGetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out); printWords(out, "return", slotAccessExpression); print(out, ".iterator();"); endMethodBody(out); } @Override protected void generateRelationAddMethodCall(Role role, String otherArg, String indexParam, PrintWriter out) { generateSetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out); super.generateRelationAddMethodCall(role, otherArg, indexParam, out); } @Override protected void generateRelationRemoveMethodCall(Role role, String otherArg, PrintWriter out) { generateSetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out); super.generateRelationRemoveMethodCall(role, otherArg, out); } @Override protected void generateBackEndIdClassBody(PrintWriter out) { if (DAP_ENABLED) { // add parameter in static initializer block newline(out); newBlock(out); print(out, "setParam(\"" + DAP_ON_CONFIG_KEY + "\", \"" + DAP_ON_CONFIG_VALUE + "\");"); closeBlock(out); } super.generateBackEndIdClassBody(out); } }