private String renderByTemplate(
      T_Transaction transaction, T_AppInfo appInfo, int userID, HttpServletRequest request)
      throws TemplateException {
    TemplateLoader templateLoader = TemplateResourceLoader.create("view/");
    Template template = templateLoader.getTemplate("m_layout");
    TemplateDataDictionary dic = TemplateDictionary.create();
    dic.setVariable("PAYTITLE", Configuration.SYSTEM_REQUESTFORM_TITLE);
    dic.setVariable("PAYURL", Configuration.SYSTEM_URL);
    dic.setVariable("STATIC_URL", Configuration.STATIC_URL);
    dic.setVariable("APPICON", appInfo.getIconPath());
    dic.setVariable("APPID", appInfo.getAppID());
    dic.setVariable("APPNAME", appInfo.getAppName());
    dic.setVariable("REFID", transaction.getRefID());
    dic.setVariable("USERID", userID + "");
    dic.setVariable("USERNAME", request.getAttribute("zme.viewerName").toString());
    dic.setVariable("DATA", request.getParameter("data"));
    dic.setVariable("PTOKEN", request.getAttribute("pToken").toString());

    String[] arrItemID = transaction.getItemIDs().split(ITEM_SEPARATE);
    String[] arrItemNames = transaction.getItemNames().split(ITEM_SEPARATE);
    String[] arrQty = transaction.getItemQuantities().split(ITEM_SEPARATE);
    String[] arrPrice = transaction.getItemPrices().split(ITEM_SEPARATE);
    String[] arrAmount = (transaction.getAmount() + "").split(ITEM_SEPARATE);
    double total = 0.0;
    for (int i = 0; i < arrItemID.length; i++) {
      double childamount = Double.parseDouble(arrAmount[i]);
      total += childamount;
      TemplateDataDictionary itemDic = dic.addSection("ITEM");
      itemDic.setVariable("ITEMNAME", arrItemNames[i]);
      itemDic.setVariable("QUANTITY", arrQty[i]);
      itemDic.setVariable("PRICE", arrPrice[i]);
      itemDic.setVariable("AMOUNT", Utils.removeDouble(childamount));
    }
    dic.setVariable("PAYTOTAL", Utils.removeDouble(total));
    dic.showSection("m_top");
    dic.showSection("m_header");
    dic.addSection("BILLING_REQUEST_FORM");
    dic.showSection("m_billing");

    TemplateDataDictionary footer = dic.addSection("m_footer");
    footer.setVariable("APPURL", Utils.removeHTTP(appInfo.appURL));
    return template.renderToString(dic);
  }
 private TemplateDataDictionary buildStandardDataDictionary(
     final GwtType type, final String moduleName) {
   final JavaType javaType = new JavaType(getFullyQualifiedTypeName(type, moduleName));
   final TemplateDataDictionary dataDictionary = TemplateDictionary.create();
   for (final GwtType reference : type.getReferences()) {
     addReference(dataDictionary, reference, moduleName);
   }
   dataDictionary.setVariable("className", javaType.getSimpleTypeName());
   dataDictionary.setVariable("packageName", javaType.getPackage().getFullyQualifiedPackageName());
   dataDictionary.setVariable(
       "placePackage",
       GwtPath.SCAFFOLD_PLACE.packageName(projectOperations.getTopLevelPackage(moduleName)));
   dataDictionary.setVariable(
       "sharedScaffoldPackage",
       GwtPath.SHARED_SCAFFOLD.packageName(projectOperations.getTopLevelPackage(moduleName)));
   dataDictionary.setVariable(
       "sharedGaePackage",
       GwtPath.SHARED_GAE.packageName(projectOperations.getTopLevelPackage(moduleName)));
   return dataDictionary;
 }
  public GwtTemplateDataHolder getMirrorTemplateTypeDetails(
      final ClassOrInterfaceTypeDetails mirroredType,
      final Map<JavaSymbolName, GwtProxyProperty> clientSideTypeMap,
      final String moduleName) {
    final ClassOrInterfaceTypeDetails proxy = gwtTypeService.lookupProxyFromEntity(mirroredType);
    final ClassOrInterfaceTypeDetails request =
        gwtTypeService.lookupRequestFromEntity(mirroredType);
    final JavaPackage topLevelPackage = projectOperations.getTopLevelPackage(moduleName);
    final Map<GwtType, JavaType> mirrorTypeMap =
        GwtUtils.getMirrorTypeMap(mirroredType.getName(), topLevelPackage);
    mirrorTypeMap.put(GwtType.PROXY, proxy.getName());
    mirrorTypeMap.put(GwtType.REQUEST, request.getName());

    final Map<GwtType, ClassOrInterfaceTypeDetails> templateTypeDetailsMap =
        new LinkedHashMap<GwtType, ClassOrInterfaceTypeDetails>();
    final Map<GwtType, String> xmlTemplates = new LinkedHashMap<GwtType, String>();
    for (final GwtType gwtType : GwtType.getMirrorTypes()) {
      if (gwtType.getTemplate() == null) {
        continue;
      }
      TemplateDataDictionary dataDictionary =
          buildMirrorDataDictionary(
              gwtType, mirroredType, proxy, mirrorTypeMap, clientSideTypeMap, moduleName);
      gwtType.dynamicallyResolveFieldsToWatch(clientSideTypeMap);
      gwtType.dynamicallyResolveMethodsToWatch(
          mirroredType.getName(), clientSideTypeMap, topLevelPackage);
      templateTypeDetailsMap.put(
          gwtType,
          getTemplateDetails(
              dataDictionary, gwtType.getTemplate(), mirrorTypeMap.get(gwtType), moduleName));

      if (gwtType.isCreateUiXml()) {
        dataDictionary =
            buildMirrorDataDictionary(
                gwtType, mirroredType, proxy, mirrorTypeMap, clientSideTypeMap, moduleName);
        final String contents =
            getTemplateContents(gwtType.getTemplate() + "UiXml", dataDictionary);
        xmlTemplates.put(gwtType, contents);
      }
    }

    final Map<String, String> xmlMap = new LinkedHashMap<String, String>();
    final List<ClassOrInterfaceTypeDetails> typeDetails =
        new ArrayList<ClassOrInterfaceTypeDetails>();
    for (final GwtProxyProperty proxyProperty : clientSideTypeMap.values()) {
      if (!proxyProperty.isCollection() || proxyProperty.isCollectionOfProxy()) {
        continue;
      }

      TemplateDataDictionary dataDictionary = TemplateDictionary.create();
      dataDictionary.setVariable("packageName", GwtPath.MANAGED_UI.packageName(topLevelPackage));
      dataDictionary.setVariable(
          "scaffoldUiPackage", GwtPath.SCAFFOLD_UI.packageName(topLevelPackage));
      final JavaType collectionTypeImpl =
          getCollectionImplementation(proxyProperty.getPropertyType());
      addImport(dataDictionary, collectionTypeImpl);
      addImport(dataDictionary, proxyProperty.getPropertyType());

      final String collectionType = proxyProperty.getPropertyType().getSimpleTypeName();
      final String boundCollectionType =
          proxyProperty.getPropertyType().getParameters().get(0).getSimpleTypeName();

      dataDictionary.setVariable("collectionType", collectionType);
      dataDictionary.setVariable("collectionTypeImpl", collectionTypeImpl.getSimpleTypeName());
      dataDictionary.setVariable("boundCollectionType", boundCollectionType);

      final JavaType collectionEditorType =
          new JavaType(
              GwtPath.MANAGED_UI.packageName(topLevelPackage)
                  + "."
                  + boundCollectionType
                  + collectionType
                  + "Editor");
      typeDetails.add(
          getTemplateDetails(dataDictionary, "CollectionEditor", collectionEditorType, moduleName));

      dataDictionary = TemplateDictionary.create();
      dataDictionary.setVariable("packageName", GwtPath.MANAGED_UI.packageName(topLevelPackage));
      dataDictionary.setVariable(
          "scaffoldUiPackage", GwtPath.SCAFFOLD_UI.packageName(topLevelPackage));
      dataDictionary.setVariable("collectionType", collectionType);
      dataDictionary.setVariable("collectionTypeImpl", collectionTypeImpl.getSimpleTypeName());
      dataDictionary.setVariable("boundCollectionType", boundCollectionType);
      addImport(dataDictionary, proxyProperty.getPropertyType());

      final String contents = getTemplateContents("CollectionEditor" + "UiXml", dataDictionary);
      final String packagePath =
          projectOperations
              .getPathResolver()
              .getFocusedIdentifier(
                  Path.SRC_MAIN_JAVA, GwtPath.MANAGED_UI.getPackagePath(topLevelPackage));
      xmlMap.put(
          packagePath + "/" + boundCollectionType + collectionType + "Editor.ui.xml", contents);
    }

    return new GwtTemplateDataHolder(templateTypeDetailsMap, xmlTemplates, typeDetails, xmlMap);
  }
  private TemplateDataDictionary buildMirrorDataDictionary(
      final GwtType type,
      final ClassOrInterfaceTypeDetails mirroredType,
      final ClassOrInterfaceTypeDetails proxy,
      final Map<GwtType, JavaType> mirrorTypeMap,
      final Map<JavaSymbolName, GwtProxyProperty> clientSideTypeMap,
      final String moduleName) {
    final JavaType proxyType = proxy.getName();
    final JavaType javaType = mirrorTypeMap.get(type);

    final TemplateDataDictionary dataDictionary = TemplateDictionary.create();

    // Get my locator and
    final JavaType entity = mirroredType.getName();
    final String entityName = entity.getFullyQualifiedTypeName();
    final String metadataIdentificationString = mirroredType.getDeclaredByMetadataId();
    final JavaType idType = persistenceMemberLocator.getIdentifierType(entity);
    Validate.notNull(idType, "Identifier type is not available for entity '" + entityName + "'");

    final MethodParameter entityParameter = new MethodParameter(entity, "proxy");
    final ClassOrInterfaceTypeDetails request = gwtTypeService.lookupRequestFromProxy(proxy);

    final MemberTypeAdditions persistMethodAdditions =
        layerService.getMemberTypeAdditions(
            metadataIdentificationString,
            CustomDataKeys.PERSIST_METHOD.name(),
            entity,
            idType,
            LAYER_POSITION,
            entityParameter);
    Validate.notNull(
        persistMethodAdditions, "Persist method is not available for entity '" + entityName + "'");
    final String persistMethodSignature = getRequestMethodCall(request, persistMethodAdditions);
    dataDictionary.setVariable("persistMethodSignature", persistMethodSignature);

    final MemberTypeAdditions removeMethodAdditions =
        layerService.getMemberTypeAdditions(
            metadataIdentificationString,
            CustomDataKeys.REMOVE_METHOD.name(),
            entity,
            idType,
            LAYER_POSITION,
            entityParameter);
    Validate.notNull(
        removeMethodAdditions, "Remove method is not available for entity '" + entityName + "'");
    final String removeMethodSignature = getRequestMethodCall(request, removeMethodAdditions);
    dataDictionary.setVariable("removeMethodSignature", removeMethodSignature);

    final MemberTypeAdditions countMethodAdditions =
        layerService.getMemberTypeAdditions(
            metadataIdentificationString,
            CustomDataKeys.COUNT_ALL_METHOD.name(),
            entity,
            idType,
            LAYER_POSITION);
    Validate.notNull(
        countMethodAdditions, "Count method is not available for entity '" + entityName + "'");
    dataDictionary.setVariable("countEntitiesMethod", countMethodAdditions.getMethodName());

    for (final GwtType reference : type.getReferences()) {
      addReference(dataDictionary, reference, mirrorTypeMap);
    }

    addImport(dataDictionary, proxyType.getFullyQualifiedTypeName());

    final String pluralMetadataKey =
        PluralMetadata.createIdentifier(
            mirroredType.getName(),
            PhysicalTypeIdentifier.getPath(mirroredType.getDeclaredByMetadataId()));
    final PluralMetadata pluralMetadata = (PluralMetadata) metadataService.get(pluralMetadataKey);
    final String plural = pluralMetadata.getPlural();

    final String simpleTypeName = mirroredType.getName().getSimpleTypeName();
    final JavaPackage topLevelPackage = projectOperations.getTopLevelPackage(moduleName);
    dataDictionary.setVariable("className", javaType.getSimpleTypeName());
    dataDictionary.setVariable("packageName", javaType.getPackage().getFullyQualifiedPackageName());
    dataDictionary.setVariable("placePackage", GwtPath.SCAFFOLD_PLACE.packageName(topLevelPackage));
    dataDictionary.setVariable(
        "scaffoldUiPackage", GwtPath.SCAFFOLD_UI.packageName(topLevelPackage));
    dataDictionary.setVariable(
        "sharedScaffoldPackage", GwtPath.SHARED_SCAFFOLD.packageName(topLevelPackage));
    dataDictionary.setVariable("uiPackage", GwtPath.MANAGED_UI.packageName(topLevelPackage));
    dataDictionary.setVariable("name", simpleTypeName);
    dataDictionary.setVariable("pluralName", plural);
    dataDictionary.setVariable("nameUncapitalized", StringUtils.uncapitalize(simpleTypeName));
    dataDictionary.setVariable("proxy", proxyType.getSimpleTypeName());
    dataDictionary.setVariable("pluralName", plural);
    dataDictionary.setVariable(
        "proxyRenderer", GwtProxyProperty.getProxyRendererType(topLevelPackage, proxyType));

    String proxyFields = null;
    GwtProxyProperty primaryProperty = null;
    GwtProxyProperty secondaryProperty = null;
    GwtProxyProperty dateProperty = null;
    final Set<String> importSet = new HashSet<String>();

    for (final GwtProxyProperty gwtProxyProperty : clientSideTypeMap.values()) {
      // Determine if this is the primary property.
      if (primaryProperty == null) {
        // Choose the first available field.
        primaryProperty = gwtProxyProperty;
      } else if (gwtProxyProperty.isString() && !primaryProperty.isString()) {
        // Favor String properties over other types.
        secondaryProperty = primaryProperty;
        primaryProperty = gwtProxyProperty;
      } else if (secondaryProperty == null) {
        // Choose the next available property.
        secondaryProperty = gwtProxyProperty;
      } else if (gwtProxyProperty.isString() && !secondaryProperty.isString()) {
        // Favor String properties over other types.
        secondaryProperty = gwtProxyProperty;
      }

      // Determine if this is the first date property.
      if (dateProperty == null && gwtProxyProperty.isDate()) {
        dateProperty = gwtProxyProperty;
      }

      if (gwtProxyProperty.isProxy() || gwtProxyProperty.isCollectionOfProxy()) {
        if (proxyFields != null) {
          proxyFields += ", ";
        } else {
          proxyFields = "";
        }
        proxyFields += "\"" + gwtProxyProperty.getName() + "\"";
      }

      dataDictionary.addSection("fields").setVariable("field", gwtProxyProperty.getName());
      if (!isReadOnly(gwtProxyProperty.getName(), mirroredType)) {
        dataDictionary
            .addSection("editViewProps")
            .setVariable("prop", gwtProxyProperty.forEditView());
      }

      final TemplateDataDictionary propertiesSection = dataDictionary.addSection("properties");
      propertiesSection.setVariable("prop", gwtProxyProperty.getName());
      propertiesSection.setVariable(
          "propId", proxyType.getSimpleTypeName() + "_" + gwtProxyProperty.getName());
      propertiesSection.setVariable("propGetter", gwtProxyProperty.getGetter());
      propertiesSection.setVariable("propType", gwtProxyProperty.getType());
      propertiesSection.setVariable("propFormatter", gwtProxyProperty.getFormatter());
      propertiesSection.setVariable("propRenderer", gwtProxyProperty.getRenderer());
      propertiesSection.setVariable("propReadable", gwtProxyProperty.getReadableName());

      if (!isReadOnly(gwtProxyProperty.getName(), mirroredType)) {
        final TemplateDataDictionary editableSection =
            dataDictionary.addSection("editableProperties");
        editableSection.setVariable("prop", gwtProxyProperty.getName());
        editableSection.setVariable(
            "propId", proxyType.getSimpleTypeName() + "_" + gwtProxyProperty.getName());
        editableSection.setVariable("propGetter", gwtProxyProperty.getGetter());
        editableSection.setVariable("propType", gwtProxyProperty.getType());
        editableSection.setVariable("propFormatter", gwtProxyProperty.getFormatter());
        editableSection.setVariable("propRenderer", gwtProxyProperty.getRenderer());
        editableSection.setVariable("propBinder", gwtProxyProperty.getBinder());
        editableSection.setVariable("propReadable", gwtProxyProperty.getReadableName());
      }

      dataDictionary.setVariable("proxyRendererType", proxyType.getSimpleTypeName() + "Renderer");

      if (gwtProxyProperty.isProxy()
          || gwtProxyProperty.isEnum()
          || gwtProxyProperty.isCollectionOfProxy()) {
        final TemplateDataDictionary section =
            dataDictionary.addSection(
                gwtProxyProperty.isEnum() ? "setEnumValuePickers" : "setProxyValuePickers");
        section.setVariable("setValuePicker", gwtProxyProperty.getSetValuePickerMethod());
        section.setVariable("setValuePickerName", gwtProxyProperty.getSetValuePickerMethodName());
        section.setVariable("valueType", gwtProxyProperty.getValueType().getSimpleTypeName());
        section.setVariable("rendererType", gwtProxyProperty.getProxyRendererType());
        if (gwtProxyProperty.isProxy() || gwtProxyProperty.isCollectionOfProxy()) {
          String propTypeName =
              StringUtils.uncapitalize(
                  gwtProxyProperty.isCollectionOfProxy()
                      ? gwtProxyProperty
                          .getPropertyType()
                          .getParameters()
                          .get(0)
                          .getSimpleTypeName()
                      : gwtProxyProperty.getPropertyType().getSimpleTypeName());
          propTypeName = propTypeName.substring(0, propTypeName.indexOf("Proxy"));
          section.setVariable("requestInterface", propTypeName + "Request");
          section.setVariable(
              "findMethod", "find" + StringUtils.capitalize(propTypeName) + "Entries(0, 50)");
        }
        maybeAddImport(dataDictionary, importSet, gwtProxyProperty.getPropertyType());
        maybeAddImport(dataDictionary, importSet, gwtProxyProperty.getValueType());
        if (gwtProxyProperty.isCollectionOfProxy()) {
          maybeAddImport(
              dataDictionary, importSet, gwtProxyProperty.getPropertyType().getParameters().get(0));
          maybeAddImport(dataDictionary, importSet, gwtProxyProperty.getSetEditorType());
        }
      }
    }

    dataDictionary.setVariable("proxyFields", proxyFields);

    // Add a section for the mobile properties.
    if (primaryProperty != null) {
      dataDictionary.setVariable("primaryProp", primaryProperty.getName());
      dataDictionary.setVariable("primaryPropGetter", primaryProperty.getGetter());
      dataDictionary.setVariable(
          "primaryPropBuilder", primaryProperty.forMobileListView("primaryRenderer"));
      final TemplateDataDictionary section = dataDictionary.addSection("mobileProperties");
      section.setVariable("prop", primaryProperty.getName());
      section.setVariable("propGetter", primaryProperty.getGetter());
      section.setVariable("propType", primaryProperty.getType());
      section.setVariable("propRenderer", primaryProperty.getRenderer());
      section.setVariable("propRendererName", "primaryRenderer");
    } else {
      dataDictionary.setVariable("primaryProp", "id");
      dataDictionary.setVariable("primaryPropGetter", "getId");
      dataDictionary.setVariable("primaryPropBuilder", "");
    }
    if (secondaryProperty != null) {
      dataDictionary.setVariable(
          "secondaryPropBuilder", secondaryProperty.forMobileListView("secondaryRenderer"));
      final TemplateDataDictionary section = dataDictionary.addSection("mobileProperties");
      section.setVariable("prop", secondaryProperty.getName());
      section.setVariable("propGetter", secondaryProperty.getGetter());
      section.setVariable("propType", secondaryProperty.getType());
      section.setVariable("propRenderer", secondaryProperty.getRenderer());
      section.setVariable("propRendererName", "secondaryRenderer");
    } else {
      dataDictionary.setVariable("secondaryPropBuilder", "");
    }
    if (dateProperty != null) {
      dataDictionary.setVariable("datePropBuilder", dateProperty.forMobileListView("dateRenderer"));
      final TemplateDataDictionary section = dataDictionary.addSection("mobileProperties");
      section.setVariable("prop", dateProperty.getName());
      section.setVariable("propGetter", dateProperty.getGetter());
      section.setVariable("propType", dateProperty.getType());
      section.setVariable("propRenderer", dateProperty.getRenderer());
      section.setVariable("propRendererName", "dateRenderer");
    } else {
      dataDictionary.setVariable("datePropBuilder", "");
    }
    return dataDictionary;
  }