/** * Generates the "send email" method to be added to the domain type * * @param mailSenderName the name of the MailSender field (required) * @param async whether to send the email asynchronously * @param targetClassMID the MID of the class to receive the method * @param mutableTypeDetails the type to which the method is being added (required) * @return a non-<code>null</code> method */ private MethodMetadata getSendMethod( final JavaSymbolName mailSenderName, final boolean async, final String targetClassMID, final ClassOrInterfaceTypeDetailsBuilder classOrInterfaceTypeDetailsBuilder) { final String contextPath = getApplicationContextPath(); final Document document = XmlUtils.readXml(fileManager.getInputStream(contextPath)); final Element root = document.getDocumentElement(); // Make a builder for the created method's body final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); // Collect the types and names of the created method's parameters final PairList<AnnotatedJavaType, JavaSymbolName> parameters = new PairList<AnnotatedJavaType, JavaSymbolName>(); if (getSimpleMailMessageBean(root) == null) { // There's no SimpleMailMessage bean; use a local variable bodyBuilder.appendFormalLine( "org.springframework.mail.SimpleMailMessage " + LOCAL_MESSAGE_VARIABLE + " = new org.springframework.mail.SimpleMailMessage();"); // Set the from address parameters.add(STRING, new JavaSymbolName("mailFrom")); bodyBuilder.appendFormalLine(LOCAL_MESSAGE_VARIABLE + ".setFrom(mailFrom);"); // Set the subject parameters.add(STRING, new JavaSymbolName("subject")); bodyBuilder.appendFormalLine(LOCAL_MESSAGE_VARIABLE + ".setSubject(subject);"); } else { // A SimpleMailMessage bean exists; auto-wire it into the entity and use it as a template final List<AnnotationMetadataBuilder> smmAnnotations = Arrays.asList(new AnnotationMetadataBuilder(AUTOWIRED)); final FieldMetadataBuilder smmFieldBuilder = new FieldMetadataBuilder( targetClassMID, PRIVATE_TRANSIENT, smmAnnotations, new JavaSymbolName(TEMPLATE_MESSAGE_FIELD), SIMPLE_MAIL_MESSAGE); classOrInterfaceTypeDetailsBuilder.addField(smmFieldBuilder.build()); // Use the injected bean as a template (for thread safety) bodyBuilder.appendFormalLine( "org.springframework.mail.SimpleMailMessage " + LOCAL_MESSAGE_VARIABLE + " = new org.springframework.mail.SimpleMailMessage(" + TEMPLATE_MESSAGE_FIELD + ");"); } // Set the to address parameters.add(STRING, new JavaSymbolName("mailTo")); bodyBuilder.appendFormalLine(LOCAL_MESSAGE_VARIABLE + ".setTo(mailTo);"); // Set the message body parameters.add(STRING, new JavaSymbolName("message")); bodyBuilder.appendFormalLine(LOCAL_MESSAGE_VARIABLE + ".setText(message);"); bodyBuilder.newLine(); bodyBuilder.appendFormalLine(mailSenderName + ".send(" + LOCAL_MESSAGE_VARIABLE + ");"); final MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( targetClassMID, Modifier.PUBLIC, new JavaSymbolName("sendMessage"), JavaType.VOID_PRIMITIVE, parameters.getKeys(), parameters.getValues(), bodyBuilder); if (async) { if (DomUtils.findFirstElementByName("task:annotation-driven", root) == null) { // Add asynchronous email support to the application if (!StringUtils.hasText(root.getAttribute("xmlns:task"))) { // Add the "task" namespace to the Spring config file root.setAttribute("xmlns:task", SPRING_TASK_NS); root.setAttribute( "xsi:schemaLocation", root.getAttribute("xsi:schemaLocation") + " " + SPRING_TASK_NS + " " + SPRING_TASK_XSD); } root.appendChild( new XmlElementBuilder("task:annotation-driven", document) .addAttribute("executor", "asyncExecutor") .addAttribute("mode", "aspectj") .build()); root.appendChild( new XmlElementBuilder("task:executor", document) .addAttribute("id", "asyncExecutor") .addAttribute("pool-size", "${executor.poolSize}") .build()); // Write out the new Spring config file fileManager.createOrUpdateTextFileIfRequired( contextPath, XmlUtils.nodeToString(document), false); // Update the email properties file propFileOperations.addPropertyIfNotExists( Path.SPRING_CONFIG_ROOT, "email.properties", "executor.poolSize", "10", true); } methodBuilder.addAnnotation(new AnnotationMetadataBuilder(ASYNC)); } return methodBuilder.build(); }