package pt.ist.fenixframework.backend.infinispan; import java.io.PrintWriter; import pt.ist.fenixframework.atomic.ContextFactory; import pt.ist.fenixframework.atomic.DefaultContextFactory; import pt.ist.fenixframework.dml.CompilerArgs; import pt.ist.fenixframework.dml.DAPCodeGenerator; import pt.ist.fenixframework.dml.DomainClass; import pt.ist.fenixframework.dml.DomainModel; import pt.ist.fenixframework.dml.IndexesCodeGenerator; import pt.ist.fenixframework.dml.Role; import pt.ist.fenixframework.dml.Slot; import pt.ist.fenixframework.dml.ValueType; import pt.ist.fenixframework.dml.ValueTypeSerializationGenerator; public class InfinispanCodeGenerator extends IndexesCodeGenerator { protected static final String VT_SERIALIZER = ValueTypeSerializationGenerator.SERIALIZER_CLASS_SIMPLE_NAME + "." + ValueTypeSerializationGenerator.SERIALIZATION_METHOD_PREFIX; protected static final String VT_DESERIALIZER = ValueTypeSerializationGenerator.SERIALIZER_CLASS_SIMPLE_NAME + "." + ValueTypeSerializationGenerator.DESERIALIZATION_METHOD_PREFIX; public InfinispanCodeGenerator(CompilerArgs compArgs, DomainModel domainModel) { super(compArgs, domainModel); String collectionName = compArgs.getParams().get(COLLECTION_CLASS_NAME_KEY); if (collectionName == null || collectionName.isEmpty()) { setCollectionToUse("pt.ist.fenixframework.core.adt.bplustree.BPlusTree"); } } @Override protected String getDomainClassRoot() { return InfinispanDomainObject.class.getName(); } @Override protected String getBackEndName() { return InfinispanBackEnd.BACKEND_NAME; } @Override protected String getDefaultConfigClassName() { return InfinispanConfig.class.getName(); } @Override protected Class<? extends ContextFactory> getAtomicContextFactoryClass() { return DefaultContextFactory.class; } @Override protected void generateFilePreamble(String subPackageName, PrintWriter out) { super.generateFilePreamble(subPackageName, out); println(out, "import pt.ist.fenixframework.backend.infinispan.InfinispanBackEnd;"); println(out, "import pt.ist.fenixframework.backend.infinispan.OID;"); println(out, "import pt.ist.fenixframework.core.Externalization;"); println(out, "import " + ValueTypeSerializationGenerator.SERIALIZER_CLASS_FULL_NAME + ";"); println(out, "import static " + ValueTypeSerializationGenerator.SERIALIZER_CLASS_FULL_NAME + ".*;"); newline(out); } @Override protected void generateBaseClassBody(DomainClass domClass, PrintWriter out) { generateStaticSlots(domClass, out); newline(out); generateInitInstance(domClass, out); generateDefaultConstructor(domClass, out); generateSlotsAccessors(domClass, out); // Index method generation super.generateIndexMethods(domClass, out); generateRoleSlotsMethods(domClass.getRoleSlots(), out); } @Override protected void generateInitInstanceMethodBody(DomainClass domClass, PrintWriter out) { } protected void generateDefaultConstructor(DomainClass domClass, PrintWriter out) { printMethod(out, "public", "", domClass.getBaseName()); startMethodBody(out); generateBaseClassConstructorsBody(domClass, out); endMethodBody(out); } @Override protected void generateStaticRoleSlotsMultOne(Role role, Role otherRole, PrintWriter out) { generateRoleMethodAdd(role, otherRole, out); generateRoleMethodRemove(role, otherRole, out); } protected void generateRoleMethodAdd(Role role, Role otherRole, PrintWriter out) { boolean multOne = (role.getMultiplicityUpper() == 1); String otherRoleTypeFullName = getTypeFullName(otherRole.getType()); String roleTypeFullName = getTypeFullName(role.getType()); printMethod(out, "public", "void", "add", makeArg(otherRoleTypeFullName, "o1"), makeArg(roleTypeFullName, "o2"), makeArg(makeGenericType("pt.ist.fenixframework.dml.runtime.Relation", otherRoleTypeFullName,roleTypeFullName), "relation")); startMethodBody(out); print(out, "if (o1 != null)"); newBlock(out); println(out, roleTypeFullName + " old2 = o1.get" + capitalize(role.getName()) + "();"); print(out, "if (o2 != old2)"); newBlock(out); println(out, "relation.remove(o1, old2);"); print(out, "o1.set" + capitalize(role.getName()) + "$unidirectional(o2);"); closeBlock(out, false); closeBlock(out, false); endMethodBody(out); } protected void generateRoleMethodRemove(Role role, Role otherRole, PrintWriter out) { boolean multOne = (role.getMultiplicityUpper() == 1); String otherRoleTypeFullName = getTypeFullName(otherRole.getType()); String roleTypeFullName = getTypeFullName(role.getType()); printMethod(out, "public", "void", "remove", makeArg(otherRoleTypeFullName, "o1"), makeArg(roleTypeFullName, "o2")); startMethodBody(out); print(out, "if (o1 != null)"); newBlock(out); print(out, "o1.set" + capitalize(role.getName()) + "$unidirectional(null);"); closeBlock(out, false); endMethodBody(out); } @Override protected void generateSlotAccessors(DomainClass domainClass, Slot slot, PrintWriter out) { generateInfinispanGetter(domainClass, slot, out); generateInfinispanSetter(domainClass, slot, out); } protected void generateInfinispanGetter(DomainClass domainClass, Slot slot, PrintWriter out) { newline(out); printFinalMethod(out, "public", slot.getTypeName(), "get" + capitalize(slot.getName())); startMethodBody(out); generateInfinispanGetterBody(domainClass, slot, out); endMethodBody(out); } protected void generateInfinispanSetter(DomainClass domainClass, Slot slot, PrintWriter out) { newline(out); printFinalMethod(out, "public", "void", "set" + capitalize(slot.getName()), makeArg(slot.getTypeName(), slot.getName())); startMethodBody(out); generateInfinispanSetterBody(domainClass, slot, out); endMethodBody(out); } protected void generateInfinispanGetterBody(DomainClass domainClass, Slot slot, PrintWriter out) { generateGetterDAPStatement(domainClass, slot.getName(), slot.getTypeName(), out);//DAP read stats update statement println(out, "Object obj = InfinispanBackEnd.getInstance().cacheGet(getOid().getFullId() + \":" + slot.getName() + "\");"); String defaultValue; PrimitiveToWrapperEntry wrapperEntry = findWrapperEntry(slot.getTypeName()); if (wrapperEntry != null) { // then it is a primitive type defaultValue = wrapperEntry.defaultPrimitiveValue; } else { defaultValue = "null"; } println(out, "if (obj == null || obj instanceof Externalization.NullClass) { return " + defaultValue + "; }"); String returnExpression = "return (" + getReferenceType(slot.getTypeName()) + ")"; ValueType vt = slot.getSlotType(); if (vt.isBuiltin() || vt.isEnum()) { returnExpression += "obj"; } else { returnExpression += VT_DESERIALIZER + ValueTypeSerializationGenerator.makeSafeValueTypeName(vt) + "((" + getReferenceType(ValueTypeSerializationGenerator.getSerializedFormTypeName(vt)) + ")obj)"; } returnExpression += ";"; print(out, returnExpression); } protected void generateInfinispanSetterBody(DomainClass domainClass, Slot slot, PrintWriter out) { generateSetterDAPStatement(domainClass, slot.getName(), slot.getTypeName(), out);//DAP write stats update statement generateSetterTxIntrospectorStatement(domainClass, slot, out); // TxIntrospector generateIndexationInSetter(domainClass, slot, out); // Indexes onNewline(out); String slotName = slot.getName(); String setterExpression; if (findWrapperEntry(slot.getTypeName()) != null) { // then it is a primitive type setterExpression = slotName; } else { setterExpression = "(" + slotName + " == null ? Externalization.NULL_OBJECT : "; ValueType vt = slot.getSlotType(); if (vt.isBuiltin() || vt.isEnum()) { setterExpression += slotName; } else { // derived value type must be externalized setterExpression += VT_SERIALIZER + ValueTypeSerializationGenerator.makeSafeValueTypeName(vt) + "(" + slotName + ")"; } setterExpression += ")"; } print(out, "InfinispanBackEnd.getInstance().cachePut(getOid().getFullId() + \":" + slotName + "\", " + setterExpression + ");"); } @Override protected void generateRoleSlotMethodsMultOne(Role role, PrintWriter out) { super.generateRoleSlotMethodsMultOne(role, out); generateRoleSlotMethodsMultOneInternalSetter(role, out); } protected void generateRoleSlotMethodsMultOneInternalSetter(Role role, PrintWriter out) { String typeName = getTypeFullName(role.getType()); String slotName = role.getName(); String capitalizedSlotName = capitalize(slotName); String setterName = "set" + capitalizedSlotName; String methodModifiers = getMethodModifiers(); // internal setter, which does not inform the relation newline(out); printMethod(out, methodModifiers, "void", setterName + "$unidirectional", makeArg(typeName, slotName)); startMethodBody(out); print(out, "InfinispanBackEnd.getInstance().cachePut(getOid().getFullId() + \":" + slotName + "\", (" + slotName + " == null ? Externalization.NULL_OBJECT : " + slotName + ".getOid()));"); endMethodBody(out); } @Override protected void generateRoleSlotMethodsMultOneGetter(String slotName, String typeName, PrintWriter out) { newline(out); printFinalMethod(out, "public", typeName, "get" + capitalize(slotName)); startMethodBody(out); generateGetterDAPStatement(dC, slotName, typeName, out);//DAP read stats update statement println(out, "Object oid = InfinispanBackEnd.getInstance().cacheGet(getOid().getFullId() + \":" + slotName + "\");"); print(out, "return (oid == null || oid instanceof Externalization.NullClass ? null : (" + typeName + ")InfinispanBackEnd.getInstance().fromOid(oid));"); endMethodBody(out); } @Override protected void generateRoleSlotMethodsMultStar(Role role, PrintWriter out) { String typeName = getTypeFullName(role.getType()); String slotName = role.getName(); String capitalizedSlotName = capitalize(slotName); String methodModifiers = getMethodModifiers(); generateRoleSlotMethodsMultStarGetter(role, out); generateRoleSlotMethodsMultStarSetter(role, out, methodModifiers, capitalizedSlotName, typeName, slotName); generateRoleSlotMethodsMultStarRemover(role, out, methodModifiers, capitalizedSlotName, typeName, slotName); generateRoleSlotMethodsMultStarSet(role, out, methodModifiers, capitalizedSlotName, typeName); generateRoleSlotMethodsMultStarCount(role, out, methodModifiers, capitalizedSlotName); generateRoleSlotMethodsMultStarHasAnyChild(role, out, methodModifiers, capitalizedSlotName); generateRoleSlotMethodsMultStarHasChild(role, out, methodModifiers, capitalizedSlotName, typeName, slotName); generateIteratorMethod(role, out); } protected void generateRoleSlotMethodsMultStarGetter(Role role, PrintWriter out) { newline(out); printFinalMethod(out, "public", getSetTypeDeclarationFor(role), "get" + capitalize(role.getName())); startMethodBody(out); generateGetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out);//DAP read stats update statement String collectionType = getDefaultCollectionFor(role.getType().getFullName()); println(out, collectionType + " internalSet;"); println(out, "Object oid = InfinispanBackEnd.getInstance().cacheGet(getOid().getFullId() + \":" + role.getName() + "\");"); print(out, "if (oid == null || oid instanceof Externalization.NullClass)"); newBlock(out); println(out, "internalSet = new " + collectionType + "();"); print(out, "InfinispanBackEnd.getInstance().cachePut(getOid().getFullId() + \":" + role.getName() + "\", internalSet.getOid());"); closeBlock(out, false); print(out, " else"); newBlock(out); print(out, "internalSet = (" + collectionType + ")InfinispanBackEnd.getInstance().fromOid(oid);"); // print(out, "// no need to test for null. The entry must exist for sure."); closeBlock(out); print(out, "return new " + getRelationAwareTypeFor(role) + "((" + getTypeFullName(role.getOtherRole().getType()) + ") this, " + getRelationSlotNameFor(role) + ", internalSet);"); endMethodBody(out); } protected void generateRoleSlotMethodsMultStarSetter(Role role, PrintWriter out, String methodModifiers, String capitalizedSlotName, String typeName, String slotName) { newline(out); String adderMethodName = getAdderMethodName(role); printFinalMethod(out, methodModifiers, "void", adderMethodName, makeArg(typeName, slotName)); startMethodBody(out); generateRelationAddMethodCall(role, slotName, null, out); endMethodBody(out); } protected void generateRoleSlotMethodsMultStarRemover(Role role, PrintWriter out, String methodModifiers, String capitalizedSlotName, String typeName, String slotName) { String removerMethodName = getRemoverMethodName(role); newline(out); printMethod(out, methodModifiers, "void", removerMethodName, makeArg(typeName, slotName)); startMethodBody(out); generateRelationRemoveMethodCall(role, slotName, out); endMethodBody(out); } protected void generateRoleSlotMethodsMultStarCount(Role role, PrintWriter out, String methodModifiers, String capitalizedSlotName) { newline(out); printMethod(out, methodModifiers, "int", "get" + capitalizedSlotName + "Count"); startMethodBody(out); generateGetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out);//DAP read stats update statement printWords(out, "return get" + capitalizedSlotName + "().size();"); endMethodBody(out); } protected void generateRoleSlotMethodsMultStarHasAnyChild(Role role, PrintWriter out, String methodModifiers, String capitalizedSlotName) { newline(out); printMethod(out, methodModifiers, "boolean", "hasAny" + capitalizedSlotName); startMethodBody(out); generateGetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out);//DAP read stats update statement printWords(out, "return (get" + capitalizedSlotName + "().size() != 0);"); endMethodBody(out); } protected void generateRoleSlotMethodsMultStarHasChild(Role role, PrintWriter out, String methodModifiers, String capitalizedSlotName, String typeName, String slotName) { newline(out); printMethod(out, methodModifiers, "boolean", "has" + capitalizedSlotName, makeArg(typeName, slotName)); startMethodBody(out); generateGetterDAPStatement(dC, role.getName(), role.getType().getFullName(), out);//DAP read stats update statement printWords(out, "return get" + capitalizedSlotName + "().contains(" + slotName + ");"); endMethodBody(out); } protected void generateRoleSlotMethodsMultStarSet(Role role, PrintWriter out, String methodModifiers, String capitalizedSlotName, 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);//DAP read stats update statement print(out, "return get" + capitalizedSlotName + "();"); endMethodBody(out); } protected void generateIteratorMethod(Role role, PrintWriter out) { generateIteratorMethod(role, out, "get" + capitalize(role.getName()) + "()"); } @Override protected String getNewRoleStarSlotExpression(Role role) { return getNewRoleStarSlotExpressionWithBackingSet(role, role.getName()); } protected String getNewRoleStarSlotExpressionWithBackingSet(Role role, String theSet) { StringBuilder buf = new StringBuilder(); // generate the relation aware collection String thisType = getTypeFullName(role.getOtherRole().getType()); buf.append("new "); buf.append(getRelationAwareTypeFor(role)); buf.append("("); buf.append(theSet); buf.append(", "); buf.append("("); buf.append(thisType); buf.append(")this, "); buf.append(getRelationSlotNameFor(role)); buf.append(")"); return buf.toString(); } @Override protected String getRoleOneBaseType() { return "pt.ist.fenixframework.dml.runtime.Role"; } }